The Boxer
python decorator 본문
728x90
반응형
- 함수를 wrapping하여 함수에 추가 구문 적용을 재사용 가능하게 만드는 기능
- 쉽게 말하자면 함수의 호출 시점에 추가적인 작업을 적용 할 때 이를 재사용 가능하게 하는 기능이다
decorator가 없는 경우
def get_data_from_database():
print("start db connect")
...
print("finish db connect")
- 위와 같이 함수 실행과 끝을 관제하는 로그를 추가한다고 하면 함수의 실행 앞뒤로 로그를 추가해야 한다.
- 다만, 위와 같은 관제 기능이 모든 함수에 추가되어야 한다고 하면, 모든 부분에 동일한 소스코드를 추가해야 한다.
- decorator를 통해 위 기능을 재사용 가능하게 만들어 모든 코드에 공통적으로 적용한다.
decorator 사용
def function_logger(original_function):
def wrapper_function():
print("start function")
original_function()
print("finish function")
return wrapper_function
@function_logger
def get_data_from_database():
print("connect to database")
get_data_from_database()
>
start function
connect to database
finish function
- 로직은 다음과 같다
- function_logger 에서 실행할 함수를 인자로 받고
- wrapper_function 내부에서 추가 구문과 함께 실행
- wrapper_function 반환
- python에서는 함수를 함수의 인자로 전달 가능하며 전달된 함수가 실행되는 로직이다
- 위 예시의 함수 호출은 다음과 동일한 결과를 출력한다.
function_logger(get_data_from_database())
인자가 정의된 함수
- decorator에서 내부의 wrapper_function에서 함수 인자 혹은 키워드를 받아 원본 함수로 전달한다.
def function_logger(original_function):
def wrapper_function(*args, **kwargs):
print("start function")
original_function(*args, **kwargs)
print("finish function")
return wrapper_function
@function_logger
def get_data_from_database(db_name):
print(f"connect to {db_name}")
get_data_from_database("test")
>
start function
connect to test
finish function
인자가 정의된 decorator
- decorator를 중첩으로 사용하여 인자를 전달한다.
def function_logger(name):
print(name)
def decorated(original_function):
def wrapper_function(*args, **kwargs):
print("start function")
original_function(*args, **kwargs)
print("finish function")
return wrapper_function
return decorated
@function_logger("logger_name")
def get_data_from_database(db_name):
print(f"connect to {db_name}")
get_data_from_database("test")
>
logger_name
start function
connect to test
finish function
- function_logger 는 인자를 받기 위한 함수일 뿐이며 실제 decorating은 decorated 라는 함수에서 원본 함수를 받아 진행한다.
반환값이 정의된 함수
- 다음 예시와 같이 반환값이 있는 경우는 decorating을 수행한 후 결과값을 반환한다.
def function_logger(name):
print(name)
def decorated(original_function):
def wrapper_function(*args, **kwargs):
print("start function")
res = original_function(*args, **kwargs)
print("finish function")
return res
return wrapper_function
return decorated
@function_logger("logger_name")
def get_data_from_database(db_name):
print(f"connect to {db_name}")
return db_name
result = get_data_from_database("test")
print(result)
>
logger_name
start function
connect to test
finish function
test
728x90
반응형
'Python' 카테고리의 다른 글
pydantic 모델 파싱시 비어있는 필드에 대해 (0) | 2022.08.07 |
---|---|
python metaclass (0) | 2022.08.06 |
python mutable, immutable (0) | 2022.07.23 |
python object interning (0) | 2022.07.22 |
python dataclass (0) | 2022.07.21 |
Comments