В каком порядке применяются и вызываются Python decorators
Если у функции несколько decorators, в каком порядке они применяются при объявлении и в каком порядке выполняются при вызове?
Ответить самому
Сначала сформулируйте ответ как на собеседовании, затем откройте разбор и оцените себя.
Короткий ответ
Decorators применяются снизу вверх при создании функции: ближайший к def оборачивает первым. При вызове выполняется внешняя обертка, то есть верхний decorator получает управление первым.
Полный разбор
Код с двумя декораторами:
@a
@b
def f():
...
эквивалентен f = a(b(f)). Значит, при объявлении сначала применяется b, потом a. Итоговая переменная f указывает на результат a(...), то есть на внешнюю обертку.
При вызове порядок выглядит наоборот с точки зрения входа в wrappers: сначала вызывается wrapper от a, внутри него может вызываться wrapper от b, и только потом исходная функция. Если wrappers делают код до и после вызова, важно отдельно проговорить enter/exit порядок.
Теория
Decorator — это callable, который принимает функцию и возвращает новую функцию или callable. Несколько decorators образуют вложенные wrappers.
Типичные ошибки
- Смешать порядок применения decorators и порядок входа в wrappers.
- Забыть, что decorator выполняется при определении функции.
- Не объяснить эквивалент через f = a(b(f)).
Как отвечать на собеседовании
- Всегда рисуй эквивалент присваивания: f = a(b(f)).
- Если спрашивают execution order, уточни: application time или call time.