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>"
"<b><i>hello world</i></b>"
我大致了解装饰器,以及在大多数示例中它如何与装饰器一起使用。
在此示例中,有2个。从输出看,似乎@make_italic先执行,然后执行@make_bold。
@make_italic
@make_bold
这是否意味着对于装饰功能,它将首先运行该功能,然后移至其他装饰器的顶部?像@make_italic先那么@make_bold,而不是相反。
所以这意味着它与大多数编程语言中的自顶向下方法的规范不同吗?仅用于这种装饰器吗?还是我错了?
装饰器 包装 正在装饰的功能。这样就make_bold修饰了make_italic装饰器的结果,从而修饰了hello功能。
make_bold
make_italic
hello
该@decorator语法真的只是语法糖; 以下:
@decorator
@decorator def decorated_function(): # ...
实际执行为:
def decorated_function(): # ... decorated_function = decorator(decorated_function)
用返回的内容替换原始decorated_function对象decorator()。
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(),它也是一个调用原始函数的lambda hello()。扩展所有这些调用,您将得到:
hello()
make_bold()
lambda
make_italic()
hello() = lambda : "<b>" + fn() + "</b>" # where fn() -> lambda : "<i>" + fn() + "</i>" # where fn() -> return "hello world"
因此输出变为:
"<b>" + ("<i>" + ("hello world") + "</i>") + "</b>"