我在装饰器的定义中使用了functools.wraps
将函数的某些属性转发到其包装器。根据基于functools.update_wrapper
的functools.wraps
文档,functools.wraps
应该默认将包装函数的属性、__module__
、__name__
、__qualname__
、__annotations__
和__doc__
分配给它的包装器。但是,在我自己的用法中,我看到functools.wraps
转发我在包装函数中定义的任何属性。
import functools
def decorator(func):
func.added_attr = 'I am added.'
@functools.wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
@decorator
def foo():
pass
print(foo.added_attr)
在上面的例子中,foo
最终引用了decorator
中定义的包装器,但这个包装器也具有包装函数中定义的added_attr
。任何人都可以解释文档中未提及的这种行为吗?
注意:我在 Python 3.7 和 3.8 中测试了上面的代码。
来自update_wrapper
文档(强调我的(:
这些参数的默认值是模块级常量
WRAPPER_ASSIGNMENTS
(分配给包装函数的__module__
、__name__
、__qualname__
、__annotations__
和__doc__
、文档字符串(和WRAPPER_UPDATES
(更新包装函数的__dict__
,即实例字典(。
func.added_attr = 'I am added.'
更新func.__dict__
,update_wrapper
复制