def decorator(extra):
extra = f" {extra}"
def inner(func):
def wrapper(*args, **kwargs):
print(f"before {func.__name__}{extra}") # before를 출력
func(*args, **kwargs) # func를 실행
print(f"after {func.__name__}{extra}") # after를 출력
return wrapper
return inner
@decorator('first')
@decorator('middle')
@decorator('last')
def hello():
print('Hello')
hello() # hello가 출력되면 어떤 일이 일어날까?
before wrapper first
before wrapper middle
before hello last
Hello
after hello last
after wrapper middle
after wrapper first
- 여기서 확인할 수 있는 것은 데코레이터를 여러 개 겹쳐서 적용할 때는 바깥쪽 데코레이터부터 순서대로 적용된다는 것이다.
- 왜 그럴까 생각해보면, AST 파서에서 정의는 위에서부터 하지만 실행은 아래에서부터 한다라고 이해하면 된다.
- 정확히는 다음과 같이 생각해볼 수 있다. 어디서부터 어떻게 감싸지는 가를 생각하면 된다.
decorator("first")(decorator("second")(decorator("third")(hello)))()
@make_bold
@make_italic
def hello():
return "hello world"
can be expanded to:
- 위의 경우 정의는 위에서부터 아래로 흐르지만, 실행은 아래에서부터 위로 흐른다.
make_bold
의 람다 함수가 먼저 호출되고 이 람다 함수는 make_italic
의 람다 함수를 호출한다.
hello = make_bold(make_italic(hello))