`functools.update_wrapper` и` functools.wraps` копируют больше атрибутов, чем ожидалось - PullRequest
0 голосов
/ 31 января 2020

Я использовал 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, определенный в обернутой функции. Кто-нибудь может объяснить это поведение, которое не упомянуто в документации?

Примечание. Я тестировал приведенный выше код в Python 3.7 и 3.8.

1 Ответ

1 голос
/ 31 января 2020

Из документов update_wrapper (выделено):

Значениями по умолчанию для этих аргументов являются константы уровня модуля WRAPPER_ASSIGNMENTS (которые присваиваются функции-обертке __module__, __name__, __qualname__, __annotations__ и __doc__, строка документации) и WRAPPER_UPDATES (которая обновляет __dict__ функции-оболочки, то есть словарь экземпляров).

func.added_attr = 'I am added.' Обновления func.__dict__, которые копируются на update_wrapper

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...