装饰器实际上只是功能,而功能只是对象.
线
@make_blink
def hello_world():
# ...
基本上与
def hello_world():
# ...
hello_world = make_blink(hello_world)
除了函数对象永远不会首先分配给hello_world(它在堆栈上,要传递给装饰器).
因此,您从make_blink()返回的所有内容都将分配回hello_world.那可以是一个功能对象,但也可以是完全不同的东西.
因此,当您使用return装饰器时,您告诉Python将hello_world设置为嵌套的函数对象.当使用return decorator()时,您告诉Python使用decorator()函数的结果.在这里,这是一个字符串值.就像您这样做:
def hello_world():
"""Original function! """
return "Hello, World!"
hello_world = "" + hello_world() + ""
对于这个特定示例来说,这很好,因为hello_world()函数的主体每次都只会返回相同的字符串.
但是,如果您将原始的hello_world()函数主体更改为每次调用都返回不同的内容,该怎么办?如果您有:
import random
@make_blink
def random_greeting():
return 'Hello ' + random.choice('DonAr', 'Martijn Pieters', 'Guido van Rossum') + '!'
现在,您从make_blink()调用返回的内容将大为不同!对于模块的顶层,装饰器在导入时仅执行一次.如果使用return decorator(),则只运行一次random.choice(),并且已将random_greeting的值固定为单个静态字符串结果.
一般而言,装饰器应再次返回可调用对象.那可以是原始函数(装饰器只是在其中更新某种注册),包装函数(在调用原始函数之前或之后做额外的事情)甚至是完全不同的东西.但这并不是在任何地方都是一成不变的,而且解释器也不管.
装饰器只是在程序中使用的可重用工具.如果您对返回原始函数结果的装饰器有特定的用途,则可以随意这样做.
本文主要介绍了Python装饰器的相关知识。装饰器是可重用工具,本质是功能和对象。通过示例说明装饰器返回值的不同情况,如返回函数对象或其他内容,还探讨了原始函数返回值变化对装饰器的影响,指出装饰器一般应返回可调用对象。

被折叠的 条评论
为什么被折叠?



