async with 用于异步资源管理,要求对象实现__aenter__和__aexit__协程方法,如aiohttp.clientsession;不可用于内置open,须用aiofiles.open等异步库。

async with 用于在异步代码中安全地管理需要异步初始化和清理的资源,比如异步数据库连接、HTTP 客户端会话或文件读写(配合支持异步的库)。它不是普通 with 的简单“加 async”,而是要求所用的上下文管理器对象实现 异步版本的协议:即定义 __aenter__ 和 __aexit__ 方法。
必须是异步上下文管理器才能用 async with
普通类即使有 __enter__ 和 __exit__,也不能用于 async with。Python 会检查对象是否实现了 __aenter__ 和 __aexit__,且二者都需是 async def 定义的协程函数。
- 常见支持库:aiohttp(
aiohttp.ClientSession())、aiomysql、asyncpg、aiofiles(aiofiles.open())等 - 错误示例:
async with open(...)会报错——内置open返回的是同步上下文管理器 - 正确写法:
async with aiofiles.open('file.txt', 'r') as f:
语法结构与执行顺序
async with 块内部代码是挂起执行的,整个流程由事件循环调度:
婚纱影楼Ronger免费手机源码采用了PHPcmsV9作为后台,前端为HTML5+CSS3开发,本站适合用作婚纱类的企业手机网站。后台超级管理员账号密码为phpcms整站打包请自行上传tyny.sql数据库文件,数据库文件修改目录为/caches/configs/无法在后台更新的问题,存在这种问题的只有俩种可能,请看下面内容:一:服务器文件域名未修改请进行以下步骤的修改:修改/caches/con
- 先 await
__aenter__(),拿到返回值(常赋给as后的变量) - 执行
async with缩进内的异步语句 - 无论是否发生异常,最后都会 await
__aexit__(exc_type, exc_val, exc_tb)
手动实现一个异步上下文管理器
便于理解底层机制。例如模拟一个带异步初始化和关闭的连接:
立即学习“Python免费学习笔记(深入)”;
class AsyncConnection:
def __init__(self, url):
self.url = url
self._conn = None
<pre class='brush:python;toolbar:false;'>async def __aenter__(self):
print("正在建立异步连接...")
# 模拟耗时的异步初始化
await asyncio.sleep(0.1)
self._conn = f"CONN_TO_{self.url}"
return self._conn
async def __aexit__(self, exc_type, exc_val, exc_tb):
print("正在关闭连接...")
await asyncio.sleep(0.05)
self._conn = None
# 返回 True 可抑制异常(不常用,慎用)
return False使用方式:
async def main(): async with AsyncConnection("https://www.php.cn/link/710ba53b0d353329706ee1bedf4b9b39") as conn: print("已连接:", conn) await asyncio.sleep(0.05) # 模拟异步操作
常见陷阱与注意事项
-
async with必须在async def函数内使用,不能直接写在模块顶层或同步函数中 - 不要混用:不能在一个
async with中嵌套普通with来管理异步资源(逻辑上错位),应确保所有资源管理都是异步协议 - 异常传播正常:若
__aenter__抛出异常,__aexit__不会被调用;若主体块或__aexit__抛出异常,则按常规 Python 异常链处理 - 多个资源可连续写:
async with a as x, b as y:,等价于嵌套,但更简洁(要求 a、b 都是异步上下文管理器)









