Decorator factory
Фабрика декораторов (Decorator Factory) — это функция, которая возвращает декоратор. Она используется в тех случаях, когда в сам декоратор нужно передать дополнительные аргументы для настройки его поведения.
Зачем нужна#
Обычный декоратор принимает только один аргумент — саму декорируемую функцию.
Если вы хотите управлять логикой декоратора (например, указать количество повторений или уровень логирования), вам нужна «обёртка над обёрткой».
Фабрика позволяет создавать кастомизируемые декораторы, которые ведут себя по‑разному в зависимости от переданных параметров.
Структура фабрики#
Реализация фабрики обычно требует трёх уровней вложенности функций:
- Внешняя функция (Фабрика): принимает аргументы для настройки (например,
num_times). - Средняя функция (Декоратор): принимает саму функцию
func, которую мы хотим изменить. - Внутренняя функция (Wrapper): содержит логику, которая будет выполняться вместо оригинальной функции.
| Уровень | Название | Принимает | Задача |
|---|---|---|---|
| 1 (Outer) | Фабрика | Параметры настройки | Создать и вернуть декоратор |
| 2 (Middle) | Декоратор | Исходную функцию | Создать и вернуть обёртку |
| 3 (Inner) | Обёртка | Аргументы функции | Выполнить доп. логику и вызвать func |
Пример#
Ниже приведён пример фабрики repeat, которая заставляет функцию выполняться указанное количество раз.
import random
x = ["Gena", "Nicola", "Egor", "Sasha"]
def repeat(num_times):
def decorator(func):
def wrapper(*args, **kwargs):
# Повторяем вызов функции указанное количество раз
for _ in range(num_times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(num_times=5)
def choose(name):
print(f"Привет {name}, сегодня на твоём пути будет - {random.choice(x)}")
choose("Misa")
Ключевые мысли#
- Когда вы пишете
@repeat(num_times=5), Python сначала вызываетrepeat(5), получает назадdecoratorи только потом применяет его к функцииchoose. - Использование
*argsи**kwargsво внутренней обёртке обязательно, чтобы декоратор мог работать с функциями, принимающими любое количество аргументов. - Фабрики декораторов делают код более гибким и позволяют переиспользовать одну и ту же логику с разными настройками.