Какая область применения декоратора?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Области применения декораторов в 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 и других атрибутов. Это критически важно для логирования, документирования и отладки.
Декораторы — фундаментальный инструмент для создания чистого, модульного и переиспользуемого кода.