当我重新研究装饰器的时候,我偶然发现了一些令人困惑的代码,我发现它通过变量和函数的方式令人费解。
def get_text(name):
return "lorem ipsum, {0} dolor sit amet".format(name)
def p_decorate(func):
def func_wrapper(name):
return "<p>{0}</p>".format(func(name))
return func_wrapper
my_get_text = p_decorate(get_text)
print my_get_text("John")
# <p>Outputs lorem ipsum, John dolor sit amet</p>
我理解将函数作为变量传递的概念(这很酷)但是它多次传递的方式使我感到困惑。 my_get_text
已经被赋值给具有参数的函数(另一个函数)。然而,就在此之后,我们引用这个新变量并将参数传递给它(“John”)。 “约翰”在func_wrapper()
转移的方式也令人困惑。
my_get_text
如何能够接收更多参数以及如何将其传递给内部函数?
谢谢
答案 0 :(得分:2)
这是装饰器如何工作的演示:它们基本上将装饰函数包装到另一个内部函数中并返回它的引用。
my_get_text = p_decorate(get_text)
使用可包装函数作为参数(p_decorate
)调用函数get_text
。name
。此返回值已分配给您的变量名称my_get_text
my_get_text
现在可调用,因为它是一个函数引用。my_get_text
,则会调用由装饰器创建的功能并移交您的参数name
(在您的情况下为'John'
)。<p>
- 标记并在它们之间推送一个字符串。此字符串是从您在步骤1中提供装饰器的函数调用中获取的:它是已经修饰的调用的返回值。顺便说一下,因为每次函数修饰时都会重新定义函数func_wrapper
(参见 closure ),返回值是一个指向全新的函数引用功能。
比较内存地址:
a = p_decorate(get_text)
b = p_decorate(get_text)
print(a == b)
print(a)
print(b)
>>> False
>>> <function func_wrapper at 0x02ADFF30>
>>> <function func_wrapper at 0x02ADFF70>
函数是使用完全相同的调用定义的,但由于它们是闭包,函数指针引用另一个内存地址(即不同的函数)。