본문 바로가기

프로그래머/Python

[윤성우의 열혈 파이썬 중급편] 32. 데코레이터

출처 : 윤성우의 열혈 파이썬 : 중급

32. 데코레이터

데코레이터에 대한 이해

def deco(func):
    def df():
        print('emoticon!')
        func()
        print('emoticon!')
    return df

smile = deco(simile)    # smile 함수 전달하고 반환 결과를 smile에 저장
smile()     # 기능이 보강된 smile 함수 호출

confused = deco(confused)
confused()
  • 데코레이터 함수가, 인자로 전달된 함수에 기능을 추가하는 방식은,
    • 기능이 추가된 새로운 함수를 만들고 이 함수를 반환하는 방식이다

전달 인자가 있는 함수 기반의 데코레이터

def adder2(n1, n2):
    return n1 + n2

def adder3(n1, n2, n3):
    return n1 + n2 + n3

def adder_deco(func):
    def ad(*args):
        print(*args, sep = ' + ', end = ' ')
        print("= {0}".format(func(*args)))
    return ad

adder2 = adder_deco(adder2)
adder2(3, 4)        # 3 + 4 = 7

adder3 = adder_deco(adder3)
adder3(1, 2, 3)     # 1 + 2 + 3 = 6
  • 위의 예에서는 데코레이터를 정의하는 데 있어서 튜플의 패킹과 언패킹이 사용되었다

@ 기반으로

def deco(func):
    def df():
        print('emoticon!')
        func()
        print('emoticon!')
    return df

def smile():
    print("^_^")

smile = deco(smile)
smile()

# deco_style.py
def adder_deco(func):
    def ad(*args):
        print(*args, sep = ' + ', end = ' ')
        print("= {0}".format(func(*args)))
    return ad

@adder_deco
def adder2(n1, n2):
    return n1 + n2

@adder_deco
def adder3(n1, n2, n3):
    return n1 + n2 + n3

def main():
    adder2(3, 4)
    adder3(3, 5, 7)

main()
  • 필요한 데코레이터가 이미 존재하는 상황에서, 지금 정의하는 함수를 그 데코레이터를 통과시킬 목적이라면 위와 같이 코드를 작성하는 것이 훨씬 간결하고 보기도 좋다

데코레이터 함수 두 번 이상 통과시키기

@deco1
@deco2
def simple():
    print("simple")

# 다음과 동일하다
simple = deco1(deco2(simple))
# deco_style2.py
def deco1(func):
    def inner():
        print('deco1')
        func()
    return inner

def deco2(func):
    def inner():
        print('deco2')
        func()
    return inner

@deco1
@deco2
def simple():
    print('simple')

def main():
    simple()

main()