Что такого важного в __name__ в python? - PullRequest
6 голосов
/ 21 февраля 2020
Атрибут

A __name__ назначается для каждой функции python. Например,

>>> def f(*args, **kwargs):
...     pass
... 
>>> f.__name__
'f'

Теперь, если мы украшаем эту функцию каким-то декоратором, мы, по сути, возвращаем другую функцию с другим __name__

>>> def d(f):
...     def w(*args, **kwargs):
...         f(*args, **kwargs)
...     return w
... 
>>> f = d(f)
>>> f.__name__
'w'

Настоятельно рекомендуется использовать wraps из functools для декорирования возвращаемой функции, чтобы можно было скопировать такую ​​информацию, как __name__ и __doc__, в исходную функцию.

>>> from functools import wraps
>>> def d(f):
...     @wraps(f)
...     def w(*args, **kwargs):
...         f(*args, **kwargs)
...     return w
... 
>>> f = d(f)
>>> f.__name__
'f' 

Мой вопрос заключается в том, какие серьезные проблемы могут возникнуть если мы не используем wraps для копирования информации? Что же такого важного в __name__, что его нужно скопировать? Простой код, как и мой пример, работает нормально, если мы не используем wrap.

Одна проблема, я могу подумать, если это сериализация. Например, Django не позволяет использовать лямбда-выражения (они безымянные) для использования в качестве значения по умолчанию для полей модели.

Может кто-нибудь добавить еще несколько проблемных c примеров? Тот же вопрос для декораторов классов.

...