Python21_装饰器AsyncContextManager

from contextlib import asynccontextmanager 是 Python 中用于创建异步上下文管理器的工具。

核心作用

asynccontextmanager 是一个装饰器,让你可以用异步生成器函数async def + yield)来创建上下文管理器,而不需要编写完整的类。

对比:传统 vs 现代写法

❌ 传统写法(繁琐)

from contextlib import AbstractAsyncContextManager

class MyAsyncContext(AbstractAsyncContextManager):
    async def __enter__(self):
        await setup()
        return self
    
    async def __exit__(self, exc_type, exc, tb):
        await cleanup()

✅ 现代写法(简洁)

from contextlib import asynccontextmanager

@asynccontextmanager
async def my_async_context():
    await setup()      # 进入时执行(相当于 __enter__)
    yield resource     # 返回资源给 with 语句
    await cleanup()    # 退出时执行(相当于 __exit__)

使用示例

import asyncio
from contextlib import asynccontextmanager

@asynccontextmanager
async def database_connection():
    print("🔗 连接数据库...")
    await asyncio.sleep(1)  # 模拟异步连接
    conn = {"status": "connected", "id": 123}
    try:
        yield conn  # 将连接对象交给 with 块使用
    finally:
        print("🔌 关闭数据库连接...")
        await asyncio.sleep(0.5)  # 模拟异步关闭

async def main():
    async with database_connection() as conn:
        print(f"✅ 使用连接: {conn}")
        # 这里可以执行数据库操作

asyncio.run(main())

输出:

🔗 连接数据库...
✅ 使用连接: {'status': 'connected', 'id': 123}
🔌 关闭数据库连接...

关键特性

特性 说明
async def 函数本身必须是异步的
yield 之前的代码 = __enter__,之后的 = __exit__
try/finally 确保资源一定被释放,即使发生异常
异常处理 可以用 try/except 捕获 with 块内的异常

异常处理示例

@asynccontextmanager
async def safe_operation():
    print("开始")
    try:
        yield
    except Exception as e:
        print(f"捕获异常: {e}")
        raise  # 可以选择重新抛出或处理
    finally:
        print("清理资源")

适用场景

  • 🗄️ 异步数据库连接(aiomysql, asyncpg)
  • 🌐 异步 HTTP 客户端(aiohttp, httpx)
  • 🔒 异步锁/信号量
  • 🚀 FastAPI lifespan 事件管理

FastAPI 实际应用

这是最常见的使用场景之一:

from contextlib import asynccontextmanager
from fastapi import FastAPI

@asynccontextmanager
async def lifespan(app: FastAPI):
    # 启动时:加载模型、连接数据库
    print("🚀 应用启动...")
    yield
    # 关闭时:清理资源
    print("🛑 应用关闭...")

app = FastAPI(lifespan=lifespan)

总结

方式 适用场景
contextmanager 同步代码
asynccontextmanager 异步代码(async/await)

asynccontextmanager 让你用最简洁的语法实现健壮的异步资源管理,是异步 Python 编程的必备工具。


Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐