Что такое декораторы в Python и для чего они используются

Ответ

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

По сути, декоратор является "синтаксическим сахаром" для функций высшего порядка.

Запись с использованием @:

@my_decorator
def say_hello():
    print("Hello!")

Эквивалентна следующей конструкции:

def say_hello():
    print("Hello!")

say_hello = my_decorator(say_hello)

Основные сценарии использования:

  • Логирование: Запись информации о вызове функции, ее аргументах и результате.
  • Кеширование: Сохранение результатов выполнения функции для повторного использования (например, functools.lru_cache).
  • Проверка прав доступа: Проверка, имеет ли пользователь право на выполнение определенного действия.
  • Замер времени выполнения: Измерение производительности функции.
  • Валидация данных: Проверка корректности аргументов, передаваемых в функцию.

Практический пример — декоратор для замера времени:

import time

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

@timing_decorator
def process_data(size: int):
    """Имитирует долгую обработку данных."""
    time.sleep(1)
    print(f"Обработано {size} элементов.")
    return True

# Вызов декорированной функции
process_data(1000)

# Вывод:
# Обработано 1000 элементов.
# Функция 'process_data' выполнилась за 1.0012 секунд

Декораторы помогают следовать принципу DRY (Don't Repeat Yourself) и улучшают читаемость кода, отделяя основную бизнес-логику от вспомогательной (сквозной) функциональности.