🔖 Справочник команд и синтаксиса

⚡ Краткий справочник

  • @decorator — применить декоратор к функции.
  • def wrapper(*args, **kwargs) — универсальная обёртка для любых аргументов.
  • @functools.wraps(func) — сохранить __name__ и __doc__.
  • @decorator(arg) — декоратор с аргументами (фабрика).
  • @outer
    @inner
    — стекирование: применяется снизу вверх.

Синтаксис декораторов

ЗаписьЧто делаетЭквивалент
@decoratorПрименяет декоратор к функцииfunc = decorator(func)
@decorator(arg)Декоратор с параметромfunc = decorator(arg)(func)
@a
@b
def f()
Стекированиеf = a(b(f))

*args и **kwargs в декораторах

ЗаписьНазначениеПример вызова
*argsПозиционные аргументы произвольной длиныfunc(1, 2, 3)
**kwargsИменованные аргументы произвольной длиныfunc(a=1, b=2)
*args, **kwargsУниверсальная сигнатура обёрткилюбой вызов

functools.wraps

ЗаписьЧто делаетБез неё
@functools.wraps(func)Копирует __name__, __doc__, __module__, __qualname__, __annotations__, __dict__wrapper скрывает оригинал

Декоратор-фабрика

УровеньНазначение
def retry(attempts):Принимает аргументы декоратора
def decorator(func):Принимает декорируемую функцию
def wrapper(*args, **kwargs):Оборачивает вызов

Порядок стекирования

ЗаписьПорядок выполнения
@border
@repeat
def f()
Сначала repeat, затем border
@repeat
@border
def f()
Сначала border, затем repeat

Правила использования

  • Всегда используйте def wrapper(*args, **kwargs), если декоратор должен быть универсальным.
  • Всегда возвращайте результат func(*args, **kwargs), если оригинал что-то возвращает.
  • Всегда используйте @functools.wraps(func), чтобы не терять метаданные.
  • Для декораторов с аргументами добавьте ещё один уровень вложенности.
  • Старайтесь не изменять сигнатуру декорированной функции без необходимости.
Проверить по документации: подробности о *args, **kwargs — в разделе Arbitrary Argument Lists.