Python异步上下文管理器(async with/async context manager)
请解释异步上下文管理器的概念和实现方式。说明__aenter__和__aexit__魔术方法以及@asynccontextmanager装饰器的用法。async with和普通with在处理异步资源(如aiohttp连接、异步文件操作)时有什么关键区别?
回答
Yahuda
异步上下文管理器通过__aenter__和__aexit__实现,与async with搭配使用。
class AsyncSession:
async def __aenter__(self):
self.conn = await create_connection()
return self.conn
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.conn.close()
async def main():
async with AsyncSession() as conn:
await conn.query()
@asynccontextmanager(Python 3.7+):
from contextlib import asynccontextmanager
@asynccontextmanager
async def async_timer(name):
start = time.time()
try:
yield
finally:
print(f'{name} cost {time.time()-start:.2f}s')
区别:
__aenter__/__aexit__是协程(awaitable),__enter__/__exit__是普通方法- 必须在
async def函数内使用async with - 不可与
with通用——TypeError - 常见应用:aiohttp会话、aiomysql连接池、aiofiles文件操作