Python 异步编程实战指南
深入理解 Python asyncio 的核心概念,掌握异步编程的最佳实践,提升爬虫和 IO 密集型任务的性能。
异步编程基础
Python 的 asyncio 模块提供了编写并发代码的基础设施,使用 async/await 语法让异步代码像同步代码一样易读。
核心概念
- Event Loop:事件循环,异步程序的执行引擎
- Coroutine:协程,使用
async def定义的函数 - Task:任务,对协程的封装,用于并发调度
- Future:未来结果,表示尚未完成的操作
基本用法
import asyncio
async def fetch_data(url: str) -> str:
"""模拟异步 HTTP 请求"""
await asyncio.sleep(1)
return f"Data from {url}"
async def main():
# 串行执行:耗时 3 秒
result1 = await fetch_data("https://api1.com")
result2 = await fetch_data("https://api2.com")
result3 = await fetch_data("https://api3.com")
# 并发执行:耗时 1 秒
results = await asyncio.gather(
fetch_data("https://api1.com"),
fetch_data("https://api2.com"),
fetch_data("https://api3.com"),
)
asyncio.run(main())
并发控制:Semaphore
当需要限制并发数量时,asyncio.Semaphore 是最佳选择:
async def crawl_with_limit(urls: list[str], limit: int = 10):
semaphore = asyncio.Semaphore(limit)
async def fetch(url: str):
async with semaphore:
return await fetch_data(url)
tasks = [fetch(url) for url in urls]
return await asyncio.gather(*tasks)
实际应用
异步编程在以下场景中特别有用:
- 网络爬虫:大量并发 HTTP 请求
- API 调用:聚合多个外部服务
- 文件 IO:大量文件读写操作
- 数据库查询:并发执行多个查询
提示:不是所有场景都适合异步,CPU 密集型任务应使用多进程。
总结
掌握 Python 异步编程能够显著提升 IO 密集型应用的性能。关键是理解事件循环的工作原理,合理使用 Semaphore 控制并发,以及选择合适的并发模式。