← Назад к вопросам

Можно ли закидывать элементы в декоратор?

1.8 Middle🔥 131 комментариев
#Python

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Декораторы и элементы в Python

Декоратор — это функция или класс, которые модифицируют поведение другой функции или класса. Вопрос о "закидывании элементов в декоратор" может интерпретироваться несколькими способами.

Что такое декоратор

Декоратор — это паттерн проектирования, который позволяет динамически добавлять новую функциональность к существующим объектам. В Python это реализуется через функции высшего порядка или классы, которые оборачивают исходную функцию.

Передача аргументов в декоратор

Да, в декоратор можно передавать аргументы (элементы). Это делается через создание фабрики декораторов — функции, которая возвращает сам декоратор:

def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(times=3)
def greet(name):
    print(f"Привет, {name}!")
    return name

Декоратор с несколькими аргументами

Можно передавать сложные структуры данных:

def validate_types(**type_map):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for param, expected_type in type_map.items():
                if param in kwargs:
                    if not isinstance(kwargs[param], expected_type):
                        raise TypeError(f"{param} должен быть {expected_type}")
            return func(*args, **kwargs)
        return wrapper
    return decorator

@validate_types(age=int, name=str)
def create_user(name, age):
    return {"name": name, "age": age}

Класс-декоратор со списком элементов

Можно использовать класс как декоратор:

class LogCallsWith:
    def __init__(self, handlers):
        self.handlers = handlers
    
    def __call__(self, func):
        def wrapper(*args, **kwargs):
            for handler in self.handlers:
                handler(f"Вызов {func.__name__}")
            return func(*args, **kwargs)
        return wrapper

def log_handler(msg):
    print(f"[LOG] {msg}")

@LogCallsWith([log_handler])
def process_data(data):
    return f"Обработано: {data}"

Практическое применение в Data Engineering

Декораторы используются для логирования, переповторов при ошибках, валидации входных данных и мониторинга производительности:

import functools
import time

def retry_on_fail(max_attempts=3, delay=1):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for attempt in range(max_attempts):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    if attempt == max_attempts - 1:
                        raise
                    time.sleep(delay)
            return None
        return wrapper
    return decorator

@retry_on_fail(max_attempts=3, delay=2)
def fetch_data_from_api(url):
    return requests.get(url).json()

Вывод

Декораторы — очень гибкий инструмент. Да, можно передавать в них элементы (аргументы), структуры данных, функции. Это делает код более модульным и переиспользуемым.