Python中 async await 使用汇总
在 Python 中,async 和 await 是 异步编程 的核心关键字,基于 asyncio 库实现协程(Coroutine),适用于高并发 I/O 密集型任务。以下是它们的 使用总结 和 典型场景:
一、核心概念
| 关键字 | 作用 |
|---|---|
async |
声明一个函数为 异步函数(协程),调用时返回协程对象,而非直接执行。 |
await |
在异步函数中 挂起当前协程,等待另一个协程或异步操作完成。 |
二、基础语法
1. 定义异步函数
async def fetch_data():
print("Start fetching")
await asyncio.sleep(2) # 模拟I/O操作
print("Done fetching")
return {"data": 123}
2. 调用异步函数
import asyncio
async def main():
result = await fetch_data() # 等待协程完成
print(result)
asyncio.run(main()) # 运行入口
输出:
Start fetching
(等待2秒)
Done fetching
{'data': 123}
三、使用场景
1. 高并发网络请求
import aiohttp # 异步HTTP库
async def fetch_url(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
async def main():
urls = ["http://example.com", "http://example.org"]
tasks = [fetch_url(url) for url in urls]
results = await asyncio.gather(*tasks) # 并发执行
print(results)
2. 数据库异步操作
async def get_user(db, user_id):
user = await db.fetch("SELECT * FROM users WHERE id = $1", user_id)
return user
3. 与Web框架集成(如FastAPI)
from fastapi import FastAPI
import asyncio
app = FastAPI()
@app.get("/data")
async def get_data():
await asyncio.sleep(1) # 模拟异步操作
return {"message": "Async data"}
4. 定时任务或事件循环
async def periodic_task():
while True:
print("Running task...")
await asyncio.sleep(60) # 每分钟执行一次
asyncio.create_task(periodic_task()) # 后台运行
四、关键注意事项
-
await必须在async函数内使用# 错误示例 def sync_func(): await fetch_data() # SyntaxError -
区分阻塞与非阻塞操作
-
可
await的操作:asyncio.sleep(),aiohttp.get(), 异步数据库查询等。 -
不可
await的阻塞操作:time.sleep(), 同步文件读写(需用asyncio.to_thread或专用异步库)。
-
-
并发执行多个任务
-
asyncio.gather():并行运行多个协程,等待所有完成。 -
asyncio.create_task():后台启动协程,不阻塞当前代码。
-
-
错误处理
async def safe_fetch(): try: return await fetch_data() except Exception as e: print(f"Error: {e}")
五、性能对比(同步 vs 异步)
| 场景 | 同步代码(线程/阻塞) | 异步代码(协程) |
|---|---|---|
| 1000次网络请求 | 高内存消耗(线程切换开销) | 低内存消耗(单线程并发) |
| 响应时间 | 慢(线性等待) | 快(重叠I/O等待时间) |
| 适用场景 | CPU密集型任务 | I/O密集型任务(如HTTP、DB) |
六、进阶技巧
-
async def async_gen(): for i in range(3): await asyncio.sleep(1) yield i async for item in async_gen(): print(item) -
超时控制
try: await asyncio.wait_for(fetch_data(), timeout=3.0) except asyncio.TimeoutError: print("Timeout!") -
同步与异步代码互调
-
同步 → 异步:用
asyncio.run()(仅限入口)。 -
异步 → 同步:用
asyncio.to_thread()或loop.run_in_executor()。
-
七、总结
-
何时用
async/await?-
需要高并发处理 I/O 操作(如API调用、数据库查询)。
-
避免线程/进程的开销(如C10k问题)。
-
与异步生态兼容(如FastAPI、aiohttp、asyncpg)。
-
-
何时不用?
-
纯CPU密集型任务(用多进程
multiprocessing)。 -
旧代码库或依赖同步库(需逐步迁移)。
-
掌握 async/await 可以显著提升I/O密集型应用的吞吐量,但需注意避免混合阻塞调用!
郭慕荣博客园

浙公网安备 33010602011771号