async函数未加await调用不会执行,仅返回协程对象;必须在async函数内用await调用,顶层需用asyncio.run()启动;混用同步阻塞操作会卡住事件循环。
async函数里没加await,调用就变成同步执行
Python的
函数本身不触发异步行为,只是返回一个
对象。如果你直接调用
却没写
,它根本不会运行,也不会报错——只是静默地丢弃协程对象。
常见错误现象:
(但这个警告默认可能被忽略,尤其在Jupyter或某些IDE中)。
检查所有
函数调用点:必须出现在
函数内,且前面有
顶层代码不能直接
,得用
启动
别把协程对象赋值给变量却不
,比如
——这等于什么都没做
混用同步阻塞调用(如time.sleep、requests.get)导致整个event loop卡住
asyncio event loop是单线程的,一旦执行了同步阻塞操作(比如
或
),整个协程调度就停摆,其他任务无法并发执行。
使用场景:你想并发请求10个API,但其中某个用了
,结果其余9个全在等它返回。
立即学习
“
Python免费学习笔记(深入)
”;
替换
→
替换
→ 用
或
已有同步库又没法换?用
把阻塞调用扔到线程池,但要注意开销和上下文丢失
忘记在async函数里用await调用另一个async函数
这是最隐蔽的坑:你写了两个
函数,A调用B,但在A里写了
而不是
。结果B的协程被创建又丢弃,A继续往下跑,B里的逻辑压根没执行。
Python 3.14.3
微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。
下载
示例:
,如果误写成
(没await),
会立即返回
,且
完全没跑。
逐行检查所有
函数内部的函数调用,凡返回
对象的,必须
用IDE的类型提示(如标注返回
)或mypy插件辅助识别
临时调试:如果是
,那就漏await了
await在非async函数里使用,语法直接报错
只能出现在
定义的函数体内。如果写在普通
函数、模块顶层、或者
分支里但外层不是async函数,Python会立刻抛出
。
容易被忽略的地方:条件分支嵌套深、重构时把一段逻辑剪切出来忘了补
、或者误以为装饰器(如
)自动提供了async上下文。
确认当前函数是否以
开头,不是
FastAPI/Starlette等框架中,路由处理函数必须是
,否则await无效或报错
交互式环境(如IPython)不支持顶层
,得用
前先确保在async函数里,或用
真正卡住async程序的,往往不是语法错误,而是“看起来在跑,其实没并发”——比如漏await、混进一个
、或者用
发了10个串行请求还自以为是异步。多打一行
,比猜强得多。
asynccoroutinefetch_data()await fetch_data()RuntimeWarning: coroutine 'fetch_data' was never awaitedasyncasyncawaitawaitasyncio.run(main())awaitcoro = fetch_data(); result = corotime.sleep(5)requests.get()requests.gettime.sleepawait asyncio.sleeprequests.getaiohttp.ClientSessionhttpx.AsyncClientloop.run_in_executorasyncB()await B()async def load_user(): return await db_query()db_query()load_userNonedb_queryasynccoroutineawaitAwaitable[T]print(type(some_call()))awaitasync defdefifSyntaxError: invalid syntaxasync@router.getasync defdefasync defawaitawait coroasyncio.run(coro)time.sleeprequestsprint("start") / print("done")