Skip to content

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 во внутренней обёртке обязательно, чтобы декоратор мог работать с функциями, принимающими любое количество аргументов.
  • Фабрики декораторов делают код более гибким и позволяют переиспользовать одну и ту же логику с разными настройками.