`functools.update_wrapper` 和 `functools.wraps` 复制了比预期更多的属性

`functools.update_wrapper` and `functools.wraps` copy more attributes over than expected

我用了functools.wraps in a definition of a decorator to forward some attributes of a function to its wrapper. According to the documentation of functools.wraps, which is based on functools.update_wrapperfunctools.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 文档(强调我的):

The default values for these arguments are the module level constants WRAPPER_ASSIGNMENTS (which assigns to the wrapper function’s __module__, __name__, __qualname__, __annotations__ and __doc__, the documentation string) and WRAPPER_UPDATES (which updates the wrapper function’s __dict__, i.e. the instance dictionary).

func.added_attr = 'I am added.' 更新 func.__dict__,它被 update_wrapper

复制