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
错误示例:
python基础教程至60课,这篇教程开始就为大家介绍了,为什么学习python,python有什么优点等,确实让你想快点学习python。为什么用Python作为编程入门语言? 原因很简单。 每种语言都会有它的支持者和反对者。去Google一下“why python”,你会得到很多结果,诸如应用范围广泛、开源、社区活跃、丰富的库、跨平台等等等等,也可能找到不少对它的批评,格式死板、效率低、国内用的人很少之类。不过这些优缺点的权衡都是程序员们的烦恼。作为一个想要学点
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()(除非你有特殊需求,比如嵌入到已有事件循环中)。










