你永远不会在你的wrapper 中调用包装好的func。添加通话,例如:
def my_dec(func):
def wrapper():
decoration = "decorated"
print(decoration)
# Call the decorated function and return what it returns
return func()
return wrapper
@my_dec
def my_func():
a = "Original"
print (a)
print(my_func())
现在会产生(因为func()implicitly returns None):
decorated
Original
None
如果我在包装器return func, wrapper 的返回语句中包含func,我会收到一条错误消息,指出元组对象不可调用。
这个错误一定是你做了类似的事情:
def my_dec(func):
def wrapper():
decoration = "decorated"
print(decoration)
# Now `my_dec` returns a tuple instead of a function
return func, wrapper
记得装饰is (roughly) equivalent to just doing:
def my_func():
...
my_func = my_dec(my_func)
您的 my_dec() 装饰器现在返回元组 (func, wrapper) 而不是包装函数,因此当您尝试调用 my_func() 时,实际上是在尝试“调用”已分配给 my_func 的元组.
作为一个很好的衡量标准,您应该学习如何使用functools.wraps,这是一个调用update_wrapper() 的便捷函数,它将包装器 函数更新为看起来像func:
from functools import wraps
def my_dec(func):
@wraps(func)
def wrapper():
decoration = "decorated"
print(decoration)
return func()
return wrapper
没有它你会得到:
In [4]: print(my_func.__name__)
wrapper
并带有包装:
In [9]: print(my_func.__name__)
my_func
它还会复制其他有用的属性,例如__doc__。