Как работают декораторы в Python?

Ответ

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

Почему используются: Декораторы позволяют многократно использовать логику (например, логирование, аутентификация, замер времени) для различных функций, сохраняя код чистым и модульным.

Пример простого декоратора:

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("До вызова функции")
        result = func(*args, **kwargs)
        print("После вызова функции")
        return result
    return wrapper

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

output = say_hello("Мир")
print(output)

Вывод:

До вызова функции
Привет, Мир!
После вызова функции
Hello, Мир

Ключевые моменты:

  • Декоратор принимает функцию как аргумент и возвращает новую функцию (обычно wrapper).
  • Синтаксис @decorator является синтаксическим сахаром для func = decorator(func).
  • Для сохранения метаданных (имени, docstring) оборачиваемой функции используют functools.wraps.
  • wrapper должен принимать *args и **kwargs, чтобы оборачиваемая функция могла принимать любые аргументы.

Частые применения:

  • Логирование: Запись информации о вызовах функций.
  • Замер времени: Измерение времени выполнения функций.
  • Кеширование: Сохранение результатов дорогостоящих вычислений.
  • Проверка прав доступа: Ограничение доступа к функциям.
  • Транзакции БД: Управление транзакциями для функций, работающих с базой данных.