升级 Python 3.10 后出现 asyncio 的 DeprecationWarning,最稳妥的处理方式是修改代码中获取事件循环的方式,而不是简单屏蔽警告,因为相关行为在后续版本中会被移除。
处理核心:这是代码兼容性警告,建议尽快调整代码写法,避免依赖已废弃的隐式事件循环创建行为。
- 定位:运行程序时加上 -W default 参数,定位警告产生的具体代码行。
- 改造:入口改为 asyncio.run(),内部获取循环改用 get_running_loop()。
- 验证:使用 -W error::DeprecationWarning 参数运行,确保不再触发警告。
核心代码改造
这类问题主要是代码写法不符合新版本规范,不需要修改系统配置,重点在于调整 Python 代码中的 asyncio 调用方式。
1. 入口函数调用
# 旧写法(3.10 会报警)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
# 新写法(推荐)
asyncio.run(main())2. 协程内部获取循环
在协程内部如果需要获取循环对象,不要用 get_event_loop(),改用 asyncio.get_running_loop()。
# 旧
loop = asyncio.get_event_loop()
# 新
loop = asyncio.get_running_loop()3. 任务创建参数
显式传递 loop 参数给 coroutine 创建函数(如 create_task)也被废弃了。
# 旧
task = asyncio.create_task(coro(), loop=loop)
# 新
task = asyncio.create_task(coro())完整示例对比
以下是一个完整的脚本改造前后对比,涵盖入口、内部循环获取及任务创建。
# 改造前 (Python 3.10 警告)
import asyncio
async def worker():
loop = asyncio.get_event_loop()
await asyncio.sleep(1)
async def main():
loop = asyncio.get_event_loop()
task = loop.create_task(worker())
await task
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
# 改造后 (无警告)
import asyncio
async def worker():
loop = asyncio.get_running_loop()
await asyncio.sleep(1)
async def main():
task = asyncio.create_task(worker())
await task
if __name__ == "__main__":
asyncio.run(main())验证与排查
修改完成后,将警告级别提升为错误,如果程序能正常运行且不报错,说明已消除 DeprecationWarning。
python -W error::DeprecationWarning your_script.py如果命令退出且没有输出 DeprecationWarning 相关 traceback,说明处理成功。同时观察程序功能是否正常,确保逻辑未因修改而受损。
第三方库警告处理
有时候警告不是你的代码产生的,而是依赖库。这种情况可以先向库作者提 issue,临时方案是用 filters 屏蔽特定包的警告,但不要全局屏蔽。
import warnings
# 仅屏蔽特定库的警告,例如某个第三方库
warnings.filterwarnings("ignore", category=DeprecationWarning, module="some_third_party_lib")常见坑
- 混合使用同步代码:在同步函数中调用异步代码时容易出错,确保只在异步上下文中调用 get_running_loop()。
- 测试环境不一致:本地 Python 版本可能高于生产环境,建议在 CI 流程中固定 Python 版本并开启警告检查。
参考来源
- Python 官方文档 - What's New In Python 3.10 (Asyncio 部分) - https://docs.python.org/3/whatsnew/3.10.html
- Python 官方文档 - asyncio.get_event_loop() 废弃说明 - https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.get_event_loop