@asynccontextmanager
是 Python 标准库 contextlib
中的一个装饰器,用于简化异步上下文管理器(Asynchronous Context Manager)的创建。它允许你通过一个异步生成器函数(async generator
)来定义资源的获取和释放逻辑,特别适用于需要异步操作(如网络请求、数据库连接等)的场景。
核心作用
-
管理异步资源:在异步代码中,
async with
语句需要配合实现了__aenter__
和__aexit__
方法的异步上下文管理器使用。@asynccontextmanager
可以自动将生成器函数转换为异步上下文管理器,避免手动实现这两个方法。 -
简化代码:通过
yield
关键字分离资源获取和释放逻辑:-
yield
之前:执行异步资源初始化(如连接数据库)。 -
yield
之后:执行异步清理操作(如关闭连接)。
-
import asyncio
from contextlib import asynccontextmanager
@asynccontextmanager
async def async_db_connection():
# 模拟异步连接数据库
print("Connecting to database...")
await asyncio.sleep(0.5)
db = {"status": "connected"}
try:
yield db # 将资源传递给 async with 代码块
finally:
# 模拟异步关闭连接
print("Closing database connection...")
await asyncio.sleep(0.5)
db["status"] = "disconnected"
async def main():
async with async_db_connection() as db:
print(f"Database status: {db['status']}")
# 执行数据库操作...
await asyncio.sleep(1)
asyncio.run(main())
输出:
Connecting to database...
Database status: connected
Closing database connection...
关键点
- 必须使用
async def
定义生成器函数。 - 只能有一个
yield
语句:用于分隔资源初始化和清理逻辑。 - 异常处理:通过
try...finally
确保资源释放,即使代码块中发生异常。 - 兼容性:需要 Python 3.7+,且只能在异步代码(如
async with
)中使用。
典型使用场景
- 异步数据库连接池
- 异步文件读写
- 需要异步初始化和清理的网络请求
- 管理异步任务的临时状态
通过 @asynccontextmanager
,你可以以更简洁的方式管理异步资源,同时确保代码的可读性和安全性。
(以上内容有AI自动生成)