Когда лучше использовать декоратор в Python?

«Когда лучше использовать декоратор в Python?» — вопрос из категории Python, который задают на 33% собеседований Data Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

  • Логирование и отладка: Для отслеживания вызовов функций, их аргументов и времени выполнения.
  • Кэширование (мемоизация): Для хранения результатов дорогостоящих вычислений и их повторного использования.
  • Контроль доступа и аутентификация: Для проверки прав пользователя перед выполнением функции.
  • Валидация данных: Для проверки входных или выходных аргументов функции.
  • Изменение поведения (например, ретраи): Для автоматического повторения вызова функции при сбоях.

Пример: декоратор для логирования

import functools
import time

def log_execution_time(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.perf_counter()
        result = func(*args, **kwargs)
        end_time = time.perf_counter()
        print(f"Функция {func.__name__!r} выполнена за {end_time - start_time:.4f} сек")
        return result
    return wrapper

@log_execution_time
def expensive_calculation(n):
    return sum(i * i for i in range(n))

# При вызове будет выведено время выполнения
result = expensive_calculation(10000)

Использование декораторов делает код чище, так как сквозная функциональность (cross-cutting concern) выносится в отдельные, переиспользуемые компоненты.