기존에 있는 코드에 기능을 추가할 때,
이름과 사용법을 동일하게 유지하면서 기능을 추가하기 위해
def origin(func):
def wrapper(): # wrapper 이 부분의 이름은 자유롭게
print("Origin Func")
func()
return wrapper
def copy1():
print("Copy1 Func")
@origin
def copy2():
print("Copy2 Func")
# "Origin Func Copy1 Func" 함수 호출 한번으로 2개의 함수 동시에 실행
copy1 = origin(copy1) # 이렇게 하는 방법이 있고
copy1()
copy2()
# 여기서 wrapper는 모든 인자를 받을 수 있어야 함. 즉, wrapper에서 사용하고자 하는 함수에는 인자가 모두 들어가 있어야 함.
# 그래서 본 예시에서는 copy3 가 인자 x를 받기 때문에 wrapper에서 *args,**kwargs를 표기
# 예시
def origin2(func):
def wrapper(*args,**kwargs):
print("Origin2 Func")
result = func(*args.**kwargs)
return wrapper
@orgigin2
def copy3(x):
print(f"copy 3 Func. Parameter = x")
cf) 함수의 실행 시간을 알고 싶을 때 decorator를 사용하면 쉽게 가능
from functools import wraps def func_time(func): @wraps(func) # func 데이터를 다 가지고 있음. 이렇게 하면 # func에 대한 __name__, __doc__ 다 접근 가능 # 메타데이터를 유지 def wrapper(*args,**kwargs): start = time.time() result = func(*args,**kwargs) end = time.time() print(f"elapsed time : {end-start}") return result return wrapper
cf) 함수의 호출 횟수와 해당 함수의 변수 메모리를 다르게 쓰는 방법 (nonlocal)
def parent(func): num = 0 @wraps(func) # func 데이터를 다 가지고 있음. 이렇게 하면 # func에 대한 __name__, __doc__ 다 접근 가능 # 메타데이터를 유지 def wrapper(*args,**kwargs): nonlocal num num+=1 print(f"{func.__name__} called {num} times") return func(*args,**kwargs) return wrapper # @parent # test1 = parent(test1) def test1(a,b):pass @parent def test2(a,b):pass test1(1,2) test2(2,3) test1(4,5) test1(4,5) test1(4,5) test2(2,3) test2(2,3) test1(4,5) """ 출력 결과 test1 called 1 times test2 called 1 times test1 called 2 times test1 called 3 times test1 called 4 times test2 called 2 times test2 called 3 times test1 called 5 times """
Decorator에 인자 보내기! => 한번더 감싸주면 됨
def parent(input_ = "Decorator") def decorator(func): @wraps(func) def wrapper(*args,**kwargs): print(input_) return func(*args,**kwargs) return wrapper return decorator @parent("Decorator2") def child(str_)" print(f"child, {str_}") child("test") print() @parent def child(str_)" print(f"child, {str_}") child("test") """ 출력 결과 Decorator2 child test Decorator child test """