본문 바로가기

Python

[Python] 데코레이터가 뭐야?

728x90

어떤 함수의 앞, 뒤에 꼭 넣어줘야 할 코드 또는 함수가 있는 경우 또는 함수를 수정하지 않고 추가 기능을 구현하고 싶을 때 데코레이터를 사용하여 구현할 수 있습니다. 다음은 변수를 입력받지 않은 데코레이터를 선언하는 방법입니다. 

 

def outer_function(function):
    def wrapper(*args, **kwargs):
        print('function start')
        return function(*args, **kwargs)
        print('function end')
    return wrapper

 

outer_function에서는 함수를 변수로 입력받고, wrapper에서는 변수를 입력받습니다. function start와 function end 중간에 있는 function(*args, **kwargs)가 직접적으로 기존의 함수가 실행되는 부분입니다.

 

def hello_world(*args, **kwargs):
    print('hello_world')

@outer_function
def hello_decorator(*args, **kwargs):
    sum = 0
    for arg in args:
        sum += arg
    return sum

 

위의 코드는 직접 데코레이터를 구현하는 방법과 @(어노테이션)을 사용하여 구현하는 방법을 나타내기 위한 코드입니다. 어노테이션으로 구현하기 위해서는 데코레이터를 구현한 함수의 이름이 들어가야 합니다. hello_world는 hello_world를 출력하는 기능을 하는 함수이고, hello_decorator는 입력받은 변수를 모두 더한 값을 반환하는 기능을 하는 함수입니다.

 

if __name__=='__main__':
    hello = outer_function(hello_world)
    hello() # hello_world
    print(hello_decorator(12,13)) # 25

 

코드를 실행하면 우선 hello에는 wrapper 함수가 저장되게 됩니다. 따라서 다음줄에 hello() 함수를 실행하면 hello_world 앞, 뒤에 function start, end가 붙는 것을 확인할 수 있습니다. 다음은 어노테이션을 사용하여 구현한 hello_decorator로 이미 hello에서 실행한 작업을 완료한 상태입니다. 따라서 hello_decorator 함수를 실행하면 12와 13을 더한 25를 결과로 반환하게 됩니다.

 

def outer_function_2(is_plus):
    def wrapper(function):
        def inner_wrapper(*args, **kwargs):
            print('function start')
            sum = function(*args, **kwargs)
            if is_plus:
                return sum
            else:
                return -sum
            print('function end')
        return inner_wrapper
    return wrapper

 

다음은 데코레이터에 변수를 입력받는 것을 해보겠습니다. 기존의 구조에서 한번 더 함수로 감싸주는 구조를 가지고 있습니다. is_plus가 True라면 양수를 False라면 음수를 반환합니다.

 

@outer_function_2(is_plus=False)
def add_variable(*args, **kwargs):
    sum = 0
    for arg in args:
        sum += arg
    return sum

if __name__=='__main__':
    print(add_variable(12, 13)) # -25

 

어노테이션을 이용하여 구현을 하였고, 첫번째 데코레이터와는 다르게 변수를 입력받습니다. 코드 실행 결과는 is_plus가 False이므로 12와 13을 더한 후 음수로 변환시킨 -25가 출력되게 됩니다.

728x90