Sobes.tech
Назад к вопросам
Junior — Middle
55

Как реализовать и применить паттерн декоратор в Python для расширения функциональности функций или методов?

Компании, где спрашивали
Фабрика РешенияФабрика Решения
БилайнБилайн

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

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

Определение:

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

Пример использования:

Например, можно измерять время выполнения функции и выводить его в лог, не трогая саму бизнес-логику.

import time
from functools import wraps

def timer(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        elapsed = time.time() - start
        print(f"{func.__name__} executed in {elapsed:.4f} sec")
        return result
    return wrapper

@timer
def process_data(n):
    return sum(i * i for i in range(n))

print(process_data(100000))

Пояснение кода:

Код не требуется для понимания идеи, но в примере он показывает типичный путь применения.

Сначала объявляется функция timer, которая принимает исходную функцию func. Затем внутри создаётся wrapper, который запускает замер времени до и после вызова func. Декоратор возвращает wrapper, поэтому при вызове process_data() фактически выполняется обёртка. Декоратор @wraps(func) нужен, чтобы сохранить имя, документацию и другие метаданные исходной функции.

Пошагово пример работает так:

  1. Python встречает @timer и передаёт process_data в timer.
  2. timer возвращает новую функцию wrapper.
  3. При вызове process_data(100000) вызывается уже wrapper.
  4. wrapper вызывает исходную функцию, измеряет время и печатает результат.
  5. Возвращается исходное значение process_data.

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

  • Декоратор позволяет расширять поведение без изменения исходной функции.
  • В Python это обычно функция, принимающая функцию и возвращающая функцию-обёртку.
  • Часто используется для логирования, авторизации, ретраев, кэширования и замера времени.
  • Для сохранения метаданных функции желательно использовать functools.wraps.
  • Декораторы можно применять и к методам классов, и к обычным функциям.
  • Синтаксис @decorator — это просто удобная запись для явного присваивания результата декоратора.