Python异步编程的核心是 async 和 await,它们不是线程或进程,而是协程(coroutine)的语法糖,用于在单线程中高效处理 I/O 密集型任务(比如网络请求、文件读写、数据库查询)。入门关键不是“多快”,而是理解“什么时候挂起、什么时候恢复”。
async def 定义协程函数,不是普通函数
用 async def 声明的函数,调用时不会立即执行,而是返回一个协程对象(coroutine object):
async def fetch\_data():
return "done"coro = fetch\_data() # 这行不运行函数体,只生成协程对象
print(coro) #
要真正运行它,必须交给事件循环(event loop),比如用 await(在协程内部)、asyncio.run()(在顶层)或 loop.run\_until\_complete()(低层)。
await 只能在 async 函数里用,且只能等待“可等待对象”
await 的作用是:暂停当前协程,把控制权交还给事件循环,等被等待的对象准备好(比如 HTTP 响应到达),再恢复执行。它不能用在普通函数里,也不能随意 await 任意东西。
立即学习“Python免费学习笔记(深入)”;
可等待对象包括:
- 其他协程(由 async def 定义)
- asyncio.Task(用 asyncio.create\_task() 创建的并发任务)
- asyncio.Future(底层机制,一般不用手写)
常见错误示例:
\# ❌ 错误:在普通函数里用 await
def bad\_func():
await asyncio.sleep(1) # SyntaxError❌ 错误:await 普通函数或数字
async def wrong(): await print("hello") # TypeError: object is not awaitable await 42 # 同样报错
用 asyncio.run() 快速启动事件循环
这是最简单的入门方式——不用手动管理事件循环:
import asyncio
async def main(): print("start") await asyncio.sleep(1) # 模拟耗时 I/O 操作 print("done")
asyncio.run(main()) # 自动创建、运行、关闭事件循环
注意:asyncio.run() 只能调用一次,且必须是程序入口点(不能嵌套调用)。生产环境如 Web 框架(FastAPI、aiohttp)会自己管理事件循环,你只需写 async/await 逻辑。
并发不等于并行:asyncio.gather() 是常用组合技
多个协程可以“看起来同时”运行,实际是事件循环在它们之间快速切换。用 asyncio.gather() 并发执行并收集结果:
async def get\_user(user\_id):
await asyncio.sleep(0.5) # 模拟 API 请求延迟
return f"user\_{user\_id}"async def main():
三个请求并发发出,总耗时约 0.5 秒,不是 1.5 秒
results = await asyncio.gather(
get\_user(1),
get\_user(2),
get\_user(3)
)
print(results) # \['user\_1', 'user\_2', 'user\_3'\]
asyncio.run(main())
对比同步写法:for 循环依次 await,总耗时是各次延迟之和;而 gather 让它们“重叠执行”,显著提升 I/O 密集场景效率。
用asyncio.run()启动事件循环这个写法我记住了,之前总想着自己手动创建loop,现在知道那样做反而不推荐。
Short and sweet but covers everything a beginner needs. The three awaitable types are clearly explained without diving too deep into implementation details.
协程对象这个概念我卡了很久,每次调用async函数以为会执行,结果什么也没发生。原来是我没理解事件循环的作用。
The gather() vs sequential await comparison using sleep timing was brilliant. Visualizing the time difference makes the benefit concrete.
“await不是随便什么东西都能等”这个提醒太重要了!我之前就犯过await print()的错误,看了这篇文章才知道为什么。
I've been coding Python for three years and avoided async until now. This made it seem approachable. The event loop explanation was just enough without being overwhelming.
建议再加一个创建Task的例子,create_task和gather的区别很多人也容易混淆。不过这篇文章本身已经讲得非常到位了。
The concept of “suspend and resume” finally clicked after reading this. I used to think async was just about speed, but it’s really about control flow.
作为一个从Flask转FastAPI的新手,这篇文章帮我打通了异步编程的任督二脉。现在终于知道为什么FastAPI这么快了。
I appreciate the “what not to do” examples with syntax errors. Seeing the wrong way helps me remember the right way much better.
gather的例子太直观了,0.5秒和1.5秒的对比让我真正理解了并发和并行的区别。原来异步不是让代码跑更快,而是让等待时间不浪费。