Python异步编程教程_asyncio协程基础实践

11次阅读

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

Python异步编程教程_asyncio协程基础实践

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.Taskasyncio.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()(除非你有特殊需求,比如嵌入到已有事件循环中)。

text=ZqhQzanResources