클로저는 바깥 함수의 지역 이름을 기억하는 내부 함수다. 데코레이터는 함수를 받아 다른 호출 가능 객체를 반환한다.
from functools import wraps
from time import perf_counter
def timed(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = perf_counter()
try:
return func(*args, **kwargs)
finally:
print(func.__name__, perf_counter() - start)
return wrapper`@timed`는 정의 시점에 `func = timed(func)`를 실행한 것과 같다. 인자를 받는 데코레이터는 데코레이터를 만드는 함수까지 한 겹 더 필요하다.
루프에서 람다나 내부 함수를 만들면 바깥 이름의 현재 값이 호출 시점에 조회된다. 모두 마지막 값을 보는 늦은 바인딩이 생길 수 있다. `lambda x=i: x`처럼 기본 인자에 현재 값을 저장하거나 별도 팩토리 함수로 범위를 만든다.
데코레이터가 많아지면 실제 호출 경로가 숨는다. 인증·로깅 같은 횡단 관심사에 제한하고 순서를 문서화한다.
댓글
0개아직 댓글이 없습니다.