def make_bold(fn):
return lambda : "<b>" + fn() + "</b>"
def make_italic(fn):
return lambda : "<i>" + fn() + "</i>"
@make_bold
@make_italic
def hello():
return "hello world"
helloHTML = hello()
산출: "<b><i>hello world</i></b>"
나는 대략적으로 데코레이터에 대해 이해하고 대부분의 예제에서 데코레이터 중 하나와 어떻게 작동하는지 이해합니다.
이 예에는 2 개가 있습니다. 출력에서 @make_italic
먼저 실행되고 @make_bold
.
이것은 데코 레이팅 된 함수의 경우 먼저 함수를 먼저 실행 한 다음 다른 데코레이터를 위해 맨 위로 이동한다는 것을 의미합니까? 그 반대 대신에 @make_italic
처음 처럼 @make_bold
.
그래서 이것은 대부분의 프로그래밍 언어에서 하향식 접근 방식의 표준과 다르다는 것을 의미합니까? 이 데코레이터의 경우에만? 아니면 내가 틀렸나 요?
답변
데코레이터 는 자신이 꾸미는 기능을 래핑 합니다. 그래서 데코레이터 make_bold
의 결과 make_italic
를 장식하여 hello
기능 을 장식했습니다 .
@decorator
구문은 정말 그냥 문법 설탕입니다; 다음과 같은:
@decorator
def decorated_function():
# ...
실제로 다음과 같이 실행됩니다.
def decorated_function():
# ...
decorated_function = decorator(decorated_function)
원래 decorated_function
개체를 decorator()
반환 된 항목으로 대체합니다 .
데코레이터를 쌓아 올리는 것은 바깥쪽으로 처리하는 과정을 반복합니다 .
따라서 샘플 :
@make_bold
@make_italic
def hello():
return "hello world"
다음으로 확장 할 수 있습니다.
def hello():
return "hello world"
hello = make_bold(make_italic(hello))
당신이 호출 할 때 hello()
지금, 당신은에 의해 반환 된 객체를 호출 make_bold()
정말. make_bold()
반환 된 lambda
함수 호출 그 make_bold
반환 값이다 싸서 make_italic()
또한 원래 호출 람다이다 hello()
. 이러한 모든 호출을 확장하면 다음과 같은 이점이 있습니다.
hello() = lambda : "<b>" + fn() + "</b>" # where fn() ->
lambda : "<i>" + fn() + "</i>" # where fn() ->
return "hello world"
따라서 출력은 다음과 같습니다.
"<b>" + ("<i>" + ("hello world") + "</i>") + "</b>"