wrapper
Closure
Definition
함수 내부에서 사용되는 함수를 의미한다
def closure():
x = 10
def inner():
y = 20
return x + y
return inner
p = closure()
p()
Closure Attribute
>> len(p.__closure__)
1
>> dir(p.__closure__[0].cell_contents)
['__abs__',
'__add__',
'__and__' ..
Decorator - wrapper()
Introduction
def 데코레이터이름(func): # 데코레이터는 호출할 함수를 매개변수로 받음
def wrapper(): # 호출할 함수를 감싸는 함수
func() # 매개변수로 받은 함수를 호출
return wrapper # wrapper 함수 반환
@데코레이터 # 데코레이터 지정
def 함수이름():
코드
내부 Closure 로 wrapper 이름을 꼭 써야만 작동이 된다. 다른 이름으로 바꾸니까 작동이 안된다 주의하자!!
Simple Example
def deco(func):
def wrapper():
print("before --------")
ret = func()
print('after --------')
return ret
return wrapper
@deco
def base():
print("base function")
base()
>>> before --------
>>> base function
>>> after --------
데코레이터 없이 사용하는 경우
def base():
print("base function")
deco(base)()
>>> before --------
>>> base function
>>> after --------
Decorator 의 응용
# "func"로 감싼 객체를 wrapper()를 추가 실행한다
def measure_run_time(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print("{} function running time : {} sec".format(func.__name__, int(end - start)))
return result
return wrapper
import time
@measure_run_time
def worker(delay_time):
time.sleep(delay_time)
worker(4)
>>> worker function running time : 4 sec
다중 Decorator
import time, datetime
from functools import wraps
def parameter_logger(func):
@wraps(func)
def wrapper(*args, **kwargs):
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
print("[%s] args : %s, kwargs : %s" %(timestamp, args, kwargs))
return func(*args, **kwargs)
return wrapper
def measure_run_time(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print("{} function running time : {} sec".format(func.__name__, int(end - start)))
return result
return wrapper
@measure_run_time
@parameter_logger
def worker(delay_time):
time.sleep(delay_time)
worker(3)
>>> [2018-07-14 15:28] args : (3,), kwargs : {}
>>> worker function running time : 3 sec
Class Decorator
import time
from functools import update_wrapper
class MeasureRuntime:
# 클래스 생성자 정의
def __init__(self, f):
self.func = f
update_wrapper(self, self.func)
# 클래스를 사용하기 위해 정의할 때 호출
def __call__(self, *args, **kwargs):
start = time.time()
result = self.func(*args, **kwargs)
end = time.time()
print("{} function running time : {} sec".format(self.func.__name__, int(end - start)))
return result
@MeasureRuntime
def worker(delay_time):
time.sleep(delay_time)
worker(3)
>>> worker function running time : 3 sec