Инструменты генерации документации Python API, такие как pydoc и epydoc , используют интроспекцию для определения имени функции и строки документации (доступны как атрибуты __name__
и __doc__
). Ожидается, что декораторы функций с хорошим поведением сохранят эти атрибуты, поэтому такие инструменты продолжают работать должным образом (то есть декорирование функции должно сохранять документацию декорированной функции). Вы делаете это путем копирования этих атрибутов из оформленной функции в декоратор. Взгляните на update_wrapper
в модуле functools
:
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')
WRAPPER_UPDATES = ('__dict__',)
def update_wrapper(wrapper,
wrapped,
assigned = WRAPPER_ASSIGNMENTS,
updated = WRAPPER_UPDATES):
"""Update a wrapper function to look like the wrapped function
wrapper is the function to be updated
wrapped is the original function
...
"""
for attr in assigned:
setattr(wrapper, attr, getattr(wrapped, attr))
for attr in updated:
getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
...
Итак, это как минимум один пример, когда изменение атрибутов функции полезно и приемлемо.
В некоторых ситуациях полезно «аннотировать» функцию путем установки атрибута; Django использует это в нескольких местах:
Вы можете установить alters_data
в True
на модельных методах, которые меняют
базы данных, предотвращая их
вызывается в шаблонах.
Вы можете установить
allow_tags
на модельных методах, которые
будет отображаться в админке, чтобы
означает, что метод возвращает HTML
контент, который не должен быть
автоматически сбежал.
Как всегда, используйте свое суждение. Если изменение атрибутов является общепринятой практикой (например, при написании декоратора), тогда все средства продолжаются. Если он будет частью скважины документированного API, то, вероятно, тоже хорошо.