Python 语法精炼24
Python 异步编程(Asynchronous Programming) 的核心语法部分,是 Python3.5+ 的重要特性之一,涉及:
协程(coroutine)机制:
async def/await/async for/async with
同步 vs 异步
同步(Synchronous)
代码 逐行执行,一行没结束前下一行不会开始:
1 | def fetch_data(): |
执行顺序固定:Start → 等3秒 → Got: data → End
异步(Asynchronous)
异步程序 允许挂起等待任务完成,在等待期间可以执行其他任务。
这不是多线程,而是 单线程并发 —— 通过事件循环(event loop)管理任务切换。
1 | import asyncio |
输出:
1 | Start |
await asyncio.sleep(3) 会“让出控制权”给事件循环,不阻塞整个程序。
协程机制
协程(coroutine)是一种可以暂停和恢复执行的函数,是生成器机制的升级版。
对比传统函数:
| 类型 | 关键字 | 可暂停 | 可恢复执行 | 示例 |
|---|---|---|---|---|
| 普通函数 | def |
❌ | ❌ | 返回值 |
| 生成器 | def + yield |
✅ | ✅ | 生成器对象 |
| 协程 | async def + await |
✅ | ✅ | 协程对象 |
async def:定义协程函数
1 | async def my_coroutine(): |
调用时不会立即执行:
1 | result = my_coroutine() |
这是一个 协程对象(coroutine object),必须通过事件循环运行:
1 | import asyncio |
await:等待另一个协程的结果
await 关键字只能在 async def 函数中使用。
作用:
暂停当前协程的执行,等待另一个协程或异步任务完成后再恢复。
示例:
1 | import asyncio |
执行顺序:
1 | Step 1 start |
await 会挂起当前协程,让事件循环有机会去运行其他协程。
asyncio.gather():并发运行
要同时执行多个协程,也即并发,使用:
1 | async def main(): |
执行时间 ≈ 2 秒(取最长的 sleep),因为两任务同时运行。
async for:异步迭代器
用于在异步环境中遍历“异步可迭代对象”,如异步数据流、网络流。
异步迭代器:
1 | class AsyncCounter: |
使用异步 for:
1 | async def main(): |
输出:
1 | 1 |
async with:异步上下文管理器
用于管理需要异步初始化和清理的资源,例如异步锁、异步文件、数据库连接。
定义示例:
1 | class AsyncContext: |
输出:
1 | Entering... |
关键字总结
| 关键字 | 用途 | 位置 | 示例 |
|---|---|---|---|
async def |
定义协程函数 | 函数定义时 | async def f(): ... |
await |
等待异步操作结果 | 协程函数内部 | await asyncio.sleep(1) |
async for |
异步迭代 | 协程函数内部 | async for x in async_iter: |
async with |
异步上下文管理 | 协程函数内部 | async with lock: |
事件循环
事件循环(Event Loop)是协程运行的“调度核心”,它不断地从任务队列中取出准备就绪的协程来执行。
简化示意:
1 | [task1] -> await I/O -> 暂停 |
在 asyncio 中:
1 | asyncio.run(main()) # 自动创建事件循环 |
或手动管理:
1 | loop = asyncio.get_event_loop() |
实战示例
并发请求网页示例,如下:
1 | import asyncio |
三个请求几乎同时发出,速度远快于同步请求。
总结表
| 机制 | 关键字 | 功能 | 类似同步语法 | 是否可并发 |
|---|---|---|---|---|
| 定义协程 | async def |
定义可暂停函数 | def |
否 |
| 挂起等待 | await |
等待异步操作 | 调用普通函数 | 是 |
| 异步迭代 | async for |
遍历异步对象 | for |
是 |
| 异步上下文 | async with |
异步资源管理 | with |
是 |
知识延伸
| 概念 | 简述 |
|---|---|
awaitable 对象 |
可被 await 的对象(协程、Task、Future) |
| Task | 将协程包装为可调度任务 asyncio.create_task() |
| Future | 低层的异步结果占位符 |
| 并发限制 | 可用 asyncio.Semaphore() 控制并发数量 |
| 异步 I/O 库 | aiohttp, aiomysql, aioredis, asyncpg |
