본문 바로가기
개발/Python3

python3 - decorator 패턴

by Devsong26 2021. 6. 11.

자바에서 aop를 잘 쓰던 사람인지라 파이썬에도 비슷한 기능이 있나 궁금했다.

파이썬에는 decorator 패턴이라는 것이 있었다.

 

Decorator Pattern

아래의 글은 파이썬 데코레이터가 도입된 배경이다.

There is general agreement that syntactic support is desirable to the current state of affairs. Guido mentioned syntactic support for decorators in his DevDay keynote presentation at the 10th Python Conference, though he later said it was only one of several extensions he proposed there "semi-jokingly". Michael Hudson raised the topic on python-dev shortly after the conference, attributing the initial bracketed syntax to an earlier proposal on comp.lang.python by Gareth McCaughan.
Class decorations seem like an obvious next step because class definition and function definition are syntactically similar, however Guido remains unconvinced, and class decorators will almost certainly not be in Python 2.4.
The discussion continued on and off on python-dev from February 2002 through July 2004. Hundreds and hundreds of posts were made, with people proposing many possible syntax variations. Guido took a list of proposals to EuroPython 2004, where a discussion took place. Subsequent to this, he decided that we'd have the Java-style  @decorator syntax, and this appeared for the first time in 2.4a2. Barry Warsaw named this the 'pie-decorator' syntax, in honor of the Pie-thon Parrot shootout which occurred around the same time as the decorator syntax, and because the @ looks a little like a pie. Guido outlined his case on Python-dev, including this piece on some of the (many) rejected forms.

https://www.python.org/dev/peps/pep-0318/#background

 

예시

여러가지 방법이 있겠으나 필자가 사용하는 방법은 아래 예시 정도이다.

# 기본 형태
def foo(func):
    def wrapper(*args, **kwargs):
        print("### [decorator function] foo ###")
        print("# args length >> ", len(args))
        for i, v in enumerate(args):
            print("# args[{0}] >> {1}".format(i, v))
        
        print("# kwargs length >> ", len(kwargs))
        for k in kwargs:
            print("# kwarg >> {0}, value >> {1}".format(k, kwargs[k]))
        
        print("\n\n")
        func(*args, **kwargs) # func의 반환형이 없을 경우 return 안 씀
        # return func(*args, **kwargs) # func의 반환형이 있을 경우 return 씀

    return wrapper

@foo
def test(arg, flag=False):
    print("### [function] test ###")
    print("# args >> ", arg)
    print("# keyword arg flag >> ", flag)
    print("\n\n")

test("Hi", flag=True)

 

자바에서는 @Before, @AfterReturning, @Around등의 사용하지만, 파이썬에서는 개발자가 커스텀할 수 있어 편리한 것 같다.

필자의 경우 @Around 식으로 즐겨 사용한다.

 


더 많은 내용을 보시려면 아래를 참고하세요.


Reference

https://www.python.org/dev/peps/pep-0318/