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

Какая область применения декоратора?

1.7 Middle🔥 101 комментариев
#Архитектура и паттерны

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

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

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

Области применения декораторов в Python

Декораторы — один из наиболее мощных инструментов в Python для модификации поведения функций и классов. Они позволяют обёртывать функцию дополнительной функциональностью без изменения её исходного кода.

Основной принцип

Декоратор — это функция, которая принимает функцию/класс на вход и возвращает новую функцию/класс с расширенной функциональностью:

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Выполнение начато")
        result = func(*args, **kwargs)
        print("Выполнение завершено")
        return result
    return wrapper

@my_decorator
def greet(name):
    return f"Привет, {name}!"

Главные области применения

1. Логирование и трассировка

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

import logging
from functools import wraps

def log_calls(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        logging.info(f"Вызов {func.__name__}")
        result = func(*args, **kwargs)
        logging.info(f"Результат: {result}")
        return result
    return wrapper

@log_calls
def calculate_sum(a, b):
    return a + b

2. Проверка аргументов и валидация

Декораторы часто используются для валидации входных данных:

from functools import wraps

def validate_positive(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        for value in args:
            if isinstance(value, (int, float)) and value < 0:
                raise ValueError("Ожидается положительное число")
        return func(*args, **kwargs)
    return wrapper

@validate_positive
def divide(a, b):
    return a / b

3. Кэширование результатов

Декораторы применяются для мемоизации дорогостоящих вычислений:

from functools import wraps, lru_cache

def memoize(func):
    cache = {}
    @wraps(func)
    def wrapper(*args, **kwargs):
        key = (args, tuple(sorted(kwargs.items())))
        if key not in cache:
            cache[key] = func(*args, **kwargs)
        return cache[key]
    return wrapper

@memoize
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

4. Управление доступом и аутентификация

Декораторы часто используются в веб-фреймворках для проверки прав доступа:

from functools import wraps

def require_auth(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        if "Authorization" not in request.headers:
            return {"error": "Unauthorized"}
        return func(*args, **kwargs)
    return wrapper

@require_auth
def delete_user(user_id):
    pass

5. Измерение производительности

Декораторы помогают профилировать функции и мерить время выполнения:

import time
from functools import wraps

def measure_time(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        elapsed = time.time() - start
        print(f"{func.__name__} выполнена за {elapsed:.4f} сек")
        return result
    return wrapper

@measure_time
def process_data(data):
    return len(data)

6. Транзакции и управление ресурсами

Декораторы применяются для управления контекстом:

from functools import wraps

def with_database(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        db = Database.connect()
        try:
            result = func(*args, db=db, **kwargs)
            db.commit()
            return result
        except Exception:
            db.rollback()
            raise
        finally:
            db.close()
    return wrapper

@with_database
def create_user(name, email, db=None):
    return db.execute("INSERT INTO users VALUES (?, ?)", (name, email))

7. Retry и timeout паттерны

Декораторы для реализации паттернов надёжности:

import time
from functools import wraps

def retry(max_attempts=3, delay=1):
    def decorator(func):
        @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 wrapper
    return decorator

@retry(max_attempts=3, delay=2)
def fetch_data_from_api():
    pass

8. Преобразование данных

Декораторы для подготовки входных/выходных данных:

from functools import wraps
import json

def json_response(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return json.dumps(result)
    return wrapper

@json_response
def get_user_info(user_id):
    return {"id": user_id, "name": "John"}

Использование functools.wraps

Всегда используй @wraps для сохранения метаданных оригинальной функции: name, doc и других атрибутов. Это критически важно для логирования, документирования и отладки.

Декораторы — фундаментальный инструмент для создания чистого, модульного и переиспользуемого кода.