Python 3.7+contextlibпонятие
contextlib.AsyncExitStack
менеджеры
Асинхронный аналог ExitStack: динамически регистрирует и корректно закрывает несколько (async) контекстных менеджеров (Python 3.7+).
Синтаксис
async with contextlib.AsyncExitStack() as stack: ...
Нужен там, где число ресурсов известно только в рантайме: открыть N соединений в цикле нельзя одним async with, а стек примет их по одному и закроет в обратном порядке при выходе. Асинхронные менеджеры регистрируются через enter_async_context() и push_async_exit(), обычные синхронные — через те же enter_context()/callback(), что и у ExitStack; перепутать методы — самая частая ошибка. Ещё приём: pop_all() переносит уже накопленные ресурсы в новый стек, чтобы не закрывать их, если инициализация дошла до конца успешно.
Примеры
import asyncio
import contextlib
print(issubclass(contextlib.AsyncExitStack, contextlib.AbstractAsyncContextManager)) # → True
stack = contextlib.AsyncExitStack()
print(hasattr(stack, 'enter_async_context'), hasattr(stack, 'push_async_callback')) # → True True
print(hasattr(stack, 'enter_context'), hasattr(stack, 'callback')) # → True True
print(hasattr(stack, '__aenter__'), hasattr(stack, '__enter__')) # → True False
print(issubclass(contextlib.AsyncExitStack, contextlib.ExitStack)) # → False
stack.callback(print, 'закрыто')
asyncio.run(stack.aclose()) # → закрыто
См. также
Открыть в полном глоссарииdocs.python.orgСообщить о неточности