简体   繁体   中英

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

I used 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_wrapper , functools.wraps should assign the attributes, __module__ , __name__ , __qualname__ , __annotations__ , and __doc__ , of the wrapped function to its wrapper by default. However, in my own usage, I see that functools.wraps forwards whatever attribute I define in the wrapped function as well.

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)

In the example above, foo eventually references the wrapper defined in decorator , yet this wrapper also has the added_attr defined in wrapped function. Can anyone explain this behavior which is not mention in the documentation?

Note: I tested the code above in Python 3.7 and 3.8.

From the update_wrapper docs (emphasis mine):

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__ , ie the instance dictionary).

func.added_attr = 'I am added.' updates func.__dict__ , which gets copied over by update_wrapper

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM