728x90
  • import 타임이란 것을 체험?해보자.
# registration.py
# BEGIN REGISTRATION

registry = []  # <1>

def register(func):  # <2>
    print('running register(%s)' % func)  # <3>
    registry.append(func)  # <4>
    return func  # <5>

@register  # <6>
def f1():
    print('running f1()')

@register
def f2():
    print('running f2()')

def f3():  # <7>
    print('running f3()')

def main():  # <8>
    print('running main()')
    print('registry ->', registry)
    f1()
    f2()
    f3()

if __name__=='__main__':
    main()  # <9>

# END REGISTRATION

"""
$ python3 registration.py
running register(<function f1 at 0x100631bf8>)  # running main보다 먼저 실행
running register(<function f2 at 0x100631c80>)  # running main보다 먼저 실행
running main()
registry -> [<function f1 at 0x100631bf8>, <function f2 at 0x100631c80>]
running f1()
running f2()
running f3()
"""

 

# registration.py를 실행하지 않고 import하면
>>> import registration
running register(<function f1 at 0x10063b1e0>)  # decorator의 실행이 확인됨
running register(<function f2 at 0x10063b268>)

즉, decorator는 모듈이 import되자마자 실행되지만, decorated function은 명시적으로 호출될 때만 실행됨을 알 수 있다. 이 예제는 파이썬 개발자가 "import time"과 "runtime"이라고 부르는 것의 차이를 명확히 보여준다.

  • 참고
    • 위처럼 decorator와 decorated function이 한 모듈에 정의되어 있는 것은 일반적이지 않다. 대개 다른 모듈에 정의하여 사용함
    • 위처럼 decorator가 decorated function을 그대로 반환하는 것은 일반적이지 않다. 대개 내부함수를 정의해서 반환한다.
    • 그대로 반환하는 부분은 유용하지 않지만, registry.append 부분처럼 웹 프레임워크에서 "함수를 어떤 중앙의 레지스트리에 추가"하는 형태로 사용한다.
  • 이와 마찬가지로
    • class가 포함된 module을 import할 때 class variable이 실행됨
      • 이는 singleton을 아주 쉽게 구현할 때 사용
    • function을 정의할 때 default value를 mutable한 것으로 설정하면 안되는 이유가
      • function을 import할 때, default value 객체를 만든다.
      • 이후 function을 call을 할 때, import할 때 만들어진 default value를 계속 활용한다.
      • 근데, 이 default value가 mutable이었으면 기대한 바와 다르게 프로그래밍 될 수 있다.
        def test_function(a, b=[]):
            b.append(a)
            print(b)
        
        if __name__ == '__main__':
            test_function(3)  # [3], expected
            test_function(4)  # [3, 4], unexpected​
728x90

+ Recent posts