Python
[Python] 임포트타임과 런타임(class variable, decorator, mutable arguments)
프리랜서를꿈꾸는자
2022. 1. 25. 23:52
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
- class가 포함된 module을 import할 때 class variable이 실행됨
728x90