我在装饰器的定义中使用functools.wraps将函数的一些属性转发给它的包装器。根据基于functools.wraps的functools.update_wrapper文档,默认情况下,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。有人能解释一下文档中没有提到的这种行为吗?
注意:我在Python3.7和3.8中测试了上面的代码。
发布于 2020-01-31 18:46:06
来自update_wrapper文档(重点是我):
这些参数的默认值是模块级常量WRAPPER_ASSIGNMENTS (它分配给包装函数的__module__、__name__、__qualname__、__annotations__和__doc__,文档字符串)和(更新包装函数的,即实例字典).**
func.added_attr = 'I am added.'更新由update_wrapper复制的func.__dict__
https://stackoverflow.com/questions/60009512
复制相似问题