데코레이터란
- 클로저를 이용해 함수 동작을 확장하는 메타 프로그래밍 기법 중 하나
- 함수를 인자로 받아 내부에서 실행하는 클로저를 정의한 후 @<클로저> 구문을 필요한 함수 앞에 표시
- 호출자 패턴의 포장 함수를 내장한 클로저의 호출 은폐
- @<클로저> <함수 정의> 구문은 함수 참조를 자유 변수롤 갖는 클로자의 내부 포장 함수로 변경
- 고차 함수를 이용한 함수 호출은 일급 함수가 아닌 함수의 참조를 인자로 전달하는 고차 함수
- 데코레이터는 고차 함수 호출을 일급 함수로 보이게 함
함수 프로파일링
- 데코레이터를 활용하 함수에 부가기능을 추가
# example 1
import time
def p_clock(func):
def wrapper(*args):
s = time.perf_counter()
ret = func(*args)
e = time.perf_counter() - s
print("[{e:0.5f}s]{func.__name__}({'.'.join(repr(arg) for arg in args)}) -> {ret}")
return ret
return wrapper
@p_clock
def factorial(n):
return 1 if n<2 else n*factorial(n-1)
factorial(5)
# example 2
def memoize(func):
memo = {0:0, 1:1, 2:2}
def wrapper(n):
nonlocal memo
if n in memo:
return memo[n]
else:
memo[n] = func(n)
return memo[n]
return wrapper
count = 0
@memoize
def Fib(n):
global count
count += 1
return Fib(n-1) + Fib(n-2)
ret = Fib(20), count
데코레이터 함수에 인자를 추가할 때와 아닐 때의 차이
# 인자 없을 경우
def deco_func(func):
def wrapper(*args, *kwargs):
return somthings(func(*args, **kwargs))
return wrapper
@deco_func
def target_func(something):
return something
# 인자 추가시
def deco_func(something):
def additional(func):
def wrapper(*args, *kwargs):
return somthings(something, func(*args, **kwargs))
return wrapper
return additional
@deco_func("인자")
def target_func(something):
return something