Асинхронный менеджер контекста - это менеджер контекста, который может приостановить выполнение в своих методах __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)