Этот вопрос проверяет понимание механизма оборачивания функций декораторами и того, как Python применяет их синтаксисом @decorator.
Декоратор — это функция, которая принимает другую функцию и возвращает новую функцию, изменяя или расширяя её поведение. Когда мы пишем @decorator, Python подменяет исходную функцию на результат вызова декоратора. Внутри обычно создаётся "обёртка" (wrapper), которая вызывает исходную функцию и добавляет новые действия: логирование, проверку, кеширование и т.п. Таким образом, декоратор позволяет модифицировать поведение без изменения исходного кода.
Определение:
Декоратор — это функция высшего порядка, которая принимает функцию и возвращает новую функцию, обычно оборачивающую оригинальную.
То есть:
вход: функция f;
выход: функция wrapper, которая выполняет дополнительные шаги и вызывает f.
Когда Python видит:
@decorator
def func():
pass
Это равносильно:
def func():
pass
func = decorator(func)
То есть:
исходная функция создаётся;
передаётся декоратору;
заменяется на версию, которую вернул декоратор.
Python
def decorator(func):
def wrapper(*args, **kwargs):
print("before")
result = func(*args, **kwargs)
print("after")
return result
return wrapper
Если применить:
Python
@decorator
def hello():
print("hello")
То реальное выполнение:
вызов hello() → вызов wrapper(), который затем вызывает оригинальный hello.
Без дополнительных действий:
имя hello станет wrapper;
докстрока потеряется.
Поэтому часто используют:
Python
from functools import wraps
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
Это сохраняет __name__, __doc__, сигнатуру.
логирование;
тайминг;
кеширование (functools.lru_cache);
аутентификация и авторизация (Flask, FastAPI);
транзакции (SQLAlchemy);
валидация данных.
Декоратор принимает функцию, создаёт вокруг неё обёртку и возвращает её обратно. Это мощный инструмент модификации поведения без изменения исходного кода.