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
,而不是相反的。
所以这意味着它与大多数编程语言中自上而下方法的规范不同?只为这个装饰器的情况?还是我错了?
答案 0 :(得分:89)
装饰者包装他们正在装饰的功能。因此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
wrap,这是make_italic()
的返回值,它也是一个调用原始hello()
的lambda。扩展所有这些来电:
hello() = lambda : "<b>" + fn() + "</b>" # where fn() ->
lambda : "<i>" + fn() + "</i>" # where fn() ->
return "hello world"
所以输出变为:
"<b>" + ("<i>" + ("hello world") + "</i>") + "</b>"