The Boxer

python decorator 본문

Python

python decorator

Prower 2022. 8. 3. 22:46
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
  • 로직은 다음과 같다
    1. function_logger 에서 실행할 함수를 인자로 받고
    2. wrapper_function 내부에서 추가 구문과 함께 실행
    3. 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