Вопрос проверяет понимание двух ключевых механизмов Python для управления ресурсами и изменения поведения функций, что важно для написания чистого и эффективного кода.
В Python контекстные менеджеры и декораторы — это мощные инструменты, которые служат разным целям, хотя оба используют идею "оборачивания".
Контекстный менеджер предназначен для управления ресурсами и обеспечения выполнения определённых действий до и после блока кода. Чаще всего он используется с оператором with. Его основная задача — гарантировать, что ресурсы (файлы, сетевые соединения, блокировки) будут корректно выделены и, что особенно важно, освобождены, даже если в блоке кода произошла ошибка.
Пример использования встроенного контекстного менеджера для работы с файлами:
with open('file.txt', 'r') as f:
content = f.read()
# Файл автоматически закрывается здесь, после выхода из блока withКонтекстный менеджер можно создать, определив класс с методами __enter__ и __exit__, или используя функцию contextlib.contextmanager.
Декоратор — это функция (или вызываемый объект), которая принимает другую функцию или класс и возвращает модифицированную версию. Декораторы применяются для добавления функциональности (логирования, кэширования, проверки прав) без изменения исходного кода оборачиваемой функции. Они используются с помощью синтаксиса @decorator_name.
Пример простого декоратора для измерения времени выполнения:
import time
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} выполнилась за {end-start:.2f} секунд")
return result
return wrapper
@timer
def slow_function():
time.sleep(1)
return "Готово"
# При вызове slow_function() будет выведено время выполнения.
slow_function()with. Декоратор применяется с символом @ перед определением функции или класса.with. Действие декоратора распространяется на все вызовы обёрнутой функции.__enter__/__exit__). Декоратор — это функция высшего порядка, возвращающая обёртку.Итог: Используйте контекстные менеджеры, когда вам нужно гарантированно выполнить setup и teardown операции для ресурсов (открыть/закрыть, подключиться/отключиться). Декораторы же применяйте для сквозной функциональности, которая должна сопровождать вызовы функций или классов, например, для логирования, аутентификации или кэширования.