python异步编程核心是asyncio模块和协程,通过async/await语法、事件循环调度实现I/O密集型任务的高效并发,需用asyncio.run()启动,await仅限async函数内使用,多协程并发推荐asyncio.gather()。

Python异步编程的核心是 asyncio 模块和 协程(coroutine),它让单线程程序能高效处理大量 I/O 密集型任务(比如网络请求、文件读写),而不用阻塞等待。掌握协程基础,关键在于理解 async/await 语法、事件循环(Event loop)的作用,以及如何真正“并发”执行多个协程。
协程不是函数,是可等待的对象
用 async def 定义的不是普通函数,而是协程函数;调用它返回的是一个协程对象,不会立即执行:
async def fetch_data(): print("开始获取数据...") await asyncio.sleep(1) # 模拟异步I/O等待 return "数据完成" coro = fetch_data() # 此时什么都没发生,只是创建了协程对象 print(type(coro)) #
要让它运行,必须交给事件循环调度——不能直接调用 coro(),也不能用 coro.send() 手动驱动(那是生成器老方式)。正确做法是:用 await 在另一个协程里等待它,或用 asyncio.run() 启动顶层协程。
await 只能在 async 函数内部使用
await 是协程的“开关”,它暂停当前协程,把控制权交还给事件循环,让其他协程有机会运行。但它有严格限制:
立即学习“Python免费学习笔记(深入)”;
- 只能出现在
async def定义的函数中 - 后面必须跟一个 awaitable 对象(协程、
asyncio.Task、asyncio.Future,或实现了__await__的对象) - 不能在普通函数、交互式命令行顶层、或 for 循环中直接写
await
错误示例:
def bad_example(): await fetch_data() # ❌ SyntaxError:await outside async function 正确写法:
async def good_example(): result = await fetch_data() # ✅ print(result)
并发执行多个协程:用 asyncio.gather()
单个 await fetch_data() 是顺序等待;想让多个协程“同时”启动(实际是交替执行),要用 asyncio.gather() 或 asyncio.create_task():
async def main(): # 方式1:gather 并发运行,按传入顺序返回结果 results = await asyncio.gather( fetch_data(), fetch_data(), fetch_data() ) print(results) # ['数据完成', '数据完成', '数据完成'],总耗时约1秒(非3秒) # 方式2:显式创建任务,适合需要单独管理的场景 task1 = asyncio.create_task(fetch_data()) task2 = asyncio.create_task(fetch_data()) await task1 await task2
gather 是最常用、最简洁的并发入口。它会自动调度所有协程,等全部完成才返回结果列表。
asyncio.run() 是运行协程的推荐起点
Python 3.7+ 推荐用 asyncio.run(main()) 启动整个异步程序。它会自动创建事件循环、运行协程、关闭循环:
async def main(): await asyncio.gather( fetch_data(), fetch_data() ) asyncio.run(main()) # ✅ 简洁安全,无需手动管理 loop
避免手动调用 loop.run_until_complete()(除非你有特殊需求,比如嵌入到已有事件循环中)。