import time defhello(name):print("Hello, my name is "+ name)deftrack_time(func):defnew_func(*args,**kwargs): start_time = time.time()func(*args, **kwargs) end_time = time.time()print(f"Execute Time : {end_time - start_time}")return new_funchello =track_time(hello)hello("primrose")# ### 확장성을 위해 track_time이라는 데코레이터 함수를 만든다. 인자로 함수를 받고, 내부의 함수를 리턴해준다.# 리턴되는 함수는 데코레이터 함수 안에서 정의된 함수이고, 확장성을 위해 packing한다."""Hello, my name is primroseExecute Time : 2.193450927734375e-05"""
위에서 hello = track_time(hello)라는 식으로 함수를 wrapping했는데,
파이썬에서는 이것을 다음과 같이 표현이 가능하다
다음과 같이 `advanced_hello` 함수 위에 @track_time이라고 적으면 advanced_hello 함수를 인자로 받아서 track_time 함수가 decorate(장식)하여 새로운 함수가 반환된다.이름은 advanced_hello 이지만 데코레이터가 있고 없고의 결과는 완전히 다르다.@track_timedefadvanced_hello(name):print("Hello, my name is "+ name)advanced_hello("primrose")"""Hello, my name is primroseExecute Time : 3.814697265625e-06"""
위에서는 데코레이터가 하나였지만, 중첩(nested)도 가능하다.
시간을 측정하는 track_time뿐 아니라, 시작과 끝을 알려주는 데코레이터 함수도 만들었다.
defstart(func):print("start_func decorator applied")defwrapper(*args,**kwargs):print("function is called now")returnfunc(*args, **kwargs)return wrapperdeffinish(func):print("finish_func decorator applied")defwrapper(*args,**kwargs): result =func(*args, **kwargs)print("function is finished now")return resultreturn wrapper@track_time@finish@startdefnested_hello(name):print("Hello, my name is "+ name)nested_hello("primrose")"""start_func decorator appliedfinish_func decorator appliedfunction is called nowHello, my name is primrosefunction is finished nowExecute Time : 5.9604644775390625e-06"""
아래는 간단한 데코레이터 활용 예시, 피보나치(엄연히 따지자면 메모이제이션)에서 사용 가능 !
defcache_memoization(func): __cache ={}defwrapper(*args):if args in __cache:return __cache[args]else: result =func(*args) __cache.update({args: result})return resultreturn wrapper@cache_memoizationdeffibo(n):return n if n <2elsefibo(n-1)+fibo(n-2)fibo(100)