Что такое фабрика декораторов в Python?

Ответ

Фабрика декораторов — это функция высшего порядка, которая принимает аргументы и возвращает декоратор. Она позволяет создавать параметризованные декораторы, поведение которых можно настраивать при их применении.

Зачем это нужно? Стандартный декоратор не принимает аргументов. Фабрика добавляет дополнительный уровень вложенности, чтобы "захватить" параметры и передать их в логику декоратора.

Структура:

  1. Фабрика (внешняя функция): Принимает параметры (*args, **kwargs) и возвращает декоратор.
  2. Декоратор (средняя функция): Принимает декорируемую функцию (func) и возвращает обёртку.
  3. Обёртка (внутренняя функция): Выполняет основную логику, используя параметры из фабрики, и вызывает исходную функцию.

Пример: декоратор для повторного вызова функции

import functools

# Уровень 1: Фабрика, принимающая параметр `times`
def repeat(times: int):
    # Уровень 2: Сам декоратор, принимающий функцию
    def decorator(func):
        @functools.wraps(func) # Сохраняет метаданные исходной функции
        # Уровень 3: Обёртка, выполняющая логику
        def wrapper(*args, **kwargs):
            print(f"Функция '{func.__name__}' будет вызвана {times} раз.")
            last_result = None
            for _ in range(times):
                last_result = func(*args, **kwargs)
            return last_result
        return wrapper
    return decorator

# Применение фабрики для создания и вызова декоратора
@repeat(3)
def greet(name):
    print(f"Hello, {name}!")

greet("World")

# Вывод:
# Функция 'greet' будет вызвана 3 раз.
# Hello, World!
# Hello, World!
# Hello, World!

Таким образом, фабрика repeat(3) создаёт и возвращает декоратор, который уже применяется к функции greet.

Ответ 18+ 🔞

Да ты посмотри, какая хуйня придумана, блядь! Фабрика декораторов — это, сука, функция, которая принимает аргументы и возвращает тебе декоратор. Ну, типа, декоратор с настройками, понимаешь? Можно подкрутить, как тебе надо, перед тем как навесить на функцию.

А нахуя это вообще? Обычный декоратор — он как дурак, нихуя не принимает, только функцию хватает. А тут, блядь, целая фабрика: ты ей параметры суёшь, она тебе декоратор с этими параметрами внутри и выплёвывает. Уровень вложенности, конечно, пиздец, но зато гибко, ёпта!

Как это устроено, блядь:

  1. Фабрика (самая внешняя): Хватает твои настройки (*args, **kwargs) и рожает декоратор.
  2. Декоратор (средний): Хватает твою бедную функцию (func) и рожает обёртку.
  3. Обёртка (самая внутренняя): Тут уже вся магия происходит, с использованием тех настроек, что ты передал. И, само собой, вызывает исходную функцию.

Пример: декоратор, который функцию повторяет, как попугай

import functools

# Уровень 1: Фабрика. Принимает, блядь, сколько раз повторять.
def repeat(times: int):
    # Уровень 2: Сам декоратор, ждёт функцию.
    def decorator(func):
        @functools.wraps(func) # Чтобы функция не забыла, как её зовут, блядь
        # Уровень 3: Обёртка, где и происходит весь пиздец.
        def wrapper(*args, **kwargs):
            print(f"Функцию '{func.__name__}' сейчас будут ебать {times} раз подряд.")
            last_result = None
            for _ in range(times):
                last_result = func(*args, **kwargs)
            return last_result
        return wrapper
    return decorator

# Применяем: фабрике говорим "3 раза", она нам декоратор делает, и он уже вешается на функцию.
@repeat(3)
def greet(name):
    print(f"Hello, {name}!")

greet("World")

# На экране будет:
# Функцию 'greet' сейчас будут ебать 3 раз подряд.
# Hello, World!
# Hello, World!
# Hello, World!

Вот и вся магия, блядь. repeat(3) — это фабрика, которая сварганила декоратор специально для трёх повторов, и этот декоратор уже нацепился на greet. Ёперный театр, а?