python 装饰函数的流程
Flow of python decorator functions
我正在尝试理解我找到的以下解释 decorators
的示例:
#!/usr/bin/python
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 "1"
return func_wrapper
get_text = p_decorate(get_text)
print get_text("John")
这个输出是:
<p>lorem ipsum, John dolor sit amet</p>
我决定尝试更改此功能并注释掉 return func_wrapper
并将其替换为 return "1"
。
当我这样做时,出现错误:
TypeError: 'str' object is not callable
关于这个我有 2 个问题:
当行
print get_text("John")
被执行,是
def func_wrapper(name):
初始化为"John"
?此行之后的事件顺序是 运行?
为什么我会收到这个错误,因为最后,不是最终返回了 string
吗?
如果有人能用这段代码解释事件的流程,我将不胜感激。
您在这里调用了装饰器:
get_text = p_decorate(get_text)
通常,装饰器会用另一个可调用函数(例如另一个函数)替换一个函数,或者 return 原始函数但已注册有关它的信息。
但是通过将 p_decorate()
的 return 值更改为 "1"
而不是函数包装器,您 'broke' get_text
不再是一个现在运作。您不能像调用字符串那样调用字符串对象。
之前,p_decorate()
return编辑了 func_wrapper()
函数对象,因此 get_text
被重新指向该函数。调用 get_text('John')
确实调用了那个嵌套函数。 func_wrapper()
然后确实以 'John'
作为参数调用,是的。函数毕竟只是对象,您可以将这些对象分配给您喜欢的任何有效 Python 名称。
当调用 func_wrapper()
时,它会依次调用 func()
,这是 p_decorate()
的参数。同样,函数 只是对象 ,因此调用 p_decorate(get_text)
后,func
最终仍绑定到原始 get_text
函数对象。调用 func()
调用原始函数。
您可以在 Python Tutor.
中查看完整的通话流程
补充一下。
当你想在装饰器中传递参数时,你使用了嵌套函数:
def decorator(func):
def wrapper(*args, **kwargs):
print('My args:', *args, **kwargs)
return func(*args, **kwargs)
return wrapper
所以你装饰:
def my_function(*args, **kwargs):
pass
my_function = decorator(my_function)
我正在尝试理解我找到的以下解释 decorators
的示例:
#!/usr/bin/python
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 "1"
return func_wrapper
get_text = p_decorate(get_text)
print get_text("John")
这个输出是:
<p>lorem ipsum, John dolor sit amet</p>
我决定尝试更改此功能并注释掉 return func_wrapper
并将其替换为 return "1"
。
当我这样做时,出现错误:
TypeError: 'str' object is not callable
关于这个我有 2 个问题:
当行
print get_text("John")
被执行,是
def func_wrapper(name):
初始化为
"John"
?此行之后的事件顺序是 运行?为什么我会收到这个错误,因为最后,不是最终返回了
string
吗?
如果有人能用这段代码解释事件的流程,我将不胜感激。
您在这里调用了装饰器:
get_text = p_decorate(get_text)
通常,装饰器会用另一个可调用函数(例如另一个函数)替换一个函数,或者 return 原始函数但已注册有关它的信息。
但是通过将 p_decorate()
的 return 值更改为 "1"
而不是函数包装器,您 'broke' get_text
不再是一个现在运作。您不能像调用字符串那样调用字符串对象。
之前,p_decorate()
return编辑了 func_wrapper()
函数对象,因此 get_text
被重新指向该函数。调用 get_text('John')
确实调用了那个嵌套函数。 func_wrapper()
然后确实以 'John'
作为参数调用,是的。函数毕竟只是对象,您可以将这些对象分配给您喜欢的任何有效 Python 名称。
当调用 func_wrapper()
时,它会依次调用 func()
,这是 p_decorate()
的参数。同样,函数 只是对象 ,因此调用 p_decorate(get_text)
后,func
最终仍绑定到原始 get_text
函数对象。调用 func()
调用原始函数。
您可以在 Python Tutor.
中查看完整的通话流程补充一下。
当你想在装饰器中传递参数时,你使用了嵌套函数:
def decorator(func):
def wrapper(*args, **kwargs):
print('My args:', *args, **kwargs)
return func(*args, **kwargs)
return wrapper
所以你装饰:
def my_function(*args, **kwargs):
pass
my_function = decorator(my_function)