기록하는삶

[파이썬/Python] OOP, 데코레이터(decorator_@)의 활용 본문

AI/파이썬(Python)

[파이썬/Python] OOP, 데코레이터(decorator_@)의 활용

mingchin 2021. 12. 2. 02:52
728x90
반응형

클래스 혹은 함수 등을 다룰 때 종종 등장하는 데코레이터(@)의 활용법, 그 중에서도 함수에서의 활용법에 대해 정리해보자.

파이썬의 함수는 일급 객체로(first-class object: 일반 객체에 적용 가능한 모든 연산이 지원되는 객체) 함수 자체를 변수에 할당하거나, 또 다른 함수에 변수로 집어넣는 것 등이 모두 가능하다.

따라서 함수 안에 또 다른 함수가 존재하거나, 특정 함수를 다른 함수의 독립변수로 넣어주는 경우를 빈번하게 볼 수 있는데 이런 과정을 보다 보기 좋게 표현할 수 있는 방법 중 하나가 바로 데코레이터(@)다. 예를 들어,

def star(f):
    def innerf(*args, **kargs):
        print(args[1]*30)
        f(*args, **kargs)
        print(args[1]*30)
    return innerf
    
@star
def printer(m, s):
    print(m)

printer("출력", "=")

위와 같은 코드가 있다면, @star를 선언했으므로, star의 variable인 f 자리에 printer라는 함수가 할당된다. 이후 innerf라는 함수는 f가 받아온 변수를 그대로 이어 받아(*args -> args에 "출력" , "=" 저장) 가진 뒤 실행된다.

위의 예시에서는 '@함수'의 형태로 star라는 함수에 변수를 따로 할당하지 않아 그 뒤에 정의된 printer가 f에 할당되었지만, 아래의 예시에서는 star에는 변수를 별도로 할당하고, 그 이후에 정의된 함수를 그 다음 내장된 함수의 변수로 할당하는 예시이다.

def power(ex):
    def wrap(f):
        def inner(*args):
            result = f(*args)
            return ex**result
        return inner
    return wrap
@power(2)
def two(n):
    return n**2   
    
two(3)

데코레이터가 없었다면 two(3)는 9를 출력하겠지만, @power(2)라 표현함으로써 power 함수의 변수인 ex에는 2가 할당되고, power의 내부에서 정의되는 wrap함수의 변수인 f 자리에 뒤이어 나오는 two(n) 함수를 변수로 집어넣게 된다. inner함수는 f가 받은 것과 동일한 args들을 할당 받아 실행되어, result에는 3의 제곱인 9가 답기고 결과적으로 2의 9승인 512를 출력하는 코드가 된다.

즉 특정 함수에 혹은 내장 함수에 또 다른 함수를 변수로 할당하고 싶은 경우, 그리고 해당 함수가 지닌 변수를 그대로 내부의 다른 함수에 할당하고 싶은 경우 데코레이터와 *args의 표현을 활용할 수 있다.

728x90
반응형