Сообщить об ошибке.

Декоратор @contextmanager модуля contextlib в Python

Декоратор для создания контекстных менеджеров

Синтаксис:

import contextlib

@contextlib.contextmanager

Параметры:

Возвращаемое значение:

  • функция для оператора with.

Описание:

Функция contextmanager() модуля contextlib представляет собой декоратор, который можно использовать для определения фабричной функции для оператора контекстных менеджеров with без необходимости создавать класс или отдельные методы __enter__() и __exit__().

Хотя многие объекты изначально поддерживают использование в операторах with, иногда необходимо управлять ресурсом, который сам по себе не является диспетчером контекста и не реализует метод close() для использования с функцией contextlib.closing().

Абстрактный пример для обеспечения правильного управления ресурсами:

from contextlib import contextmanager

@contextmanager
def managed_resource(*args, **kwds):
    # Код для выделения ресурса, например:
    resource = acquire_resource(*args, **kwds)
    try:
        yield resource
    finally:
        # Код для освобождения ресурса, например:
        release_resource(resource)

>>> with managed_resource(timeout=3600) as resource:
...     # Ресурс освобождается в конце этого блока,
...     # Даже если код в блоке вызывает исключение

Декорируемая функция, при вызове, должна возвращать генератор-итератор. Этот генератор-итератор должен выдавать ровно одно значение, которое будет привязано к целям в предложении with оператора as, если оно есть.

В тот момент, когда генератор дает результат, выполняется блок, вложенный в оператор with. Затем генератор возобновляется после выхода из блока. Если в блоке возникает необработанное исключение, оно повторно вызывается внутри генератора в точке, где произошел выход. Таким образом, можно использовать оператор try…exceptfinally, чтобы перехватить ошибку, если она есть или убедиться, что произошла какая-то очистка. Если исключение перехвачено просто для того, чтобы зарегистрировать его или выполнить какое-либо действие, а не полностью его подавить, то генератор должен повторно вызвать это исключение. В противном случае менеджер контекста генератора укажет оператору with, что исключение обработано, и выполнение возобновится с оператором, следующим сразу за оператором with.

Функция contextlib.contextmanager() использует класс contextlib.ContextDecorator(), поэтому создаваемые им менеджеры контекста могут использоваться как в качестве декораторов, так и в операторах with.

При использовании в качестве декоратора новый экземпляр генератора неявно создается при каждом вызове функции. Это позволяет другим одноразовым менеджерам контекста, созданным с использованием декоратора @contextmanager, выполнить требование, чтобы менеджеры контекста поддерживали множественные вызовы.