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

Асинхронный контекстный менеджер async with

Асинхронный менеджер контекста - это менеджер контекста, который может приостановить выполнение в своих методах __aenter__() и __aexit__().

Асинхронные менеджеры контекста могут использоваться в асинхронном операторе with.

Методы асинхронного менеджера контекста.

Протокол асинхронных контекстных менеджеров реализован с помощью пары методов, которые позволяют в пользовательских классах определять контекст среды выполнения, который вводится до выполнения тела инструкции и завершается при завершении инструкции.

object.__aenter__(self):

Асинхронный метод object.__aenter__() семантически похож на метод __enter__() простого менеджера контекста, с той лишь разницей, что он должен вернуть awaitable.

object.__aexit__(self, exc_type, exc_value, traceback):

Асинхронный метод object.__aexit__() семантически похож на метод __exit__() простого менеджера контекста, с той лишь разницей, что он должен возвращать awaitable.

Пример класса асинхронного менеджера контекста:

class AsyncContextManager:
    async def __aenter__(self):
        await log('Вход в контекст')

    async def __aexit__(self, exc_type, exc, tb):
        await log('Выход из контекста')

Для создания асинхронных контекстных менеджеров можно использовать декоратор @asynccontextmanager, предлагаемый встроенным модулем contextlib.

Асинхронный оператор async with.

Асинхронный оператор async with может использоваться только в теле асинхронной функции (сопрограммы).

Когда оператор async with используется вне тела функции сопрограммы, то поднимается исключение SyntaxError.

Следующий код:

async with EXPRESSION as TARGET:
    SUITE

Семантически эквивалентен:

manager = (EXPRESSION)
aexit = type(manager).__aexit__
aenter = type(manager).__aenter__
value = await aenter(manager)
hit_except = False

try:
    TARGET = value
    SUITE
except:
    hit_except = True
    if not await aexit(manager, *sys.exc_info()):
        raise
finally:
    if not hit_except:
        await aexit(manager, None, None, None)