为什么需要异步编程 在处理大量I/O操作时,同步代码会严重阻塞程序执行。异步编程可以让程序在等待I/O时继续执行其他任务。
同步 vs 异步对比 import timedef fetch_data (url ): time.sleep(2 ) return f"Data from {url} " def main (): start = time.time() results = [] for url in ['url1' , 'url2' , 'url3' ]: results.append(fetch_data(url)) print (f"耗时: {time.time() - start} 秒" ) main()
import asyncioasync def fetch_data (url ): await asyncio.sleep(2 ) return f"Data from {url} " async def main (): start = time.time() tasks = [fetch_data(url) for url in ['url1' , 'url2' , 'url3' ]] results = await asyncio.gather(*tasks) print (f"耗时: {time.time() - start} 秒" ) print (results) asyncio.run(main())
asyncio 核心概念 1. Coroutine(协程) async def my_coroutine (): """协程函数,使用 async def 定义""" await some_async_operation()
2. Task(任务) task = asyncio.create_task(my_coroutine()) result = await task
3. Future(未来对象) future = asyncio.Future() future.set_result("完成" ) result = await future
实战案例:并发HTTP请求 import asyncioimport aiohttpasync def fetch (session, url ): async with session.get(url) as response: return await response.text() async def fetch_all (urls ): async with aiohttp.ClientSession() as session: tasks = [fetch(session, url) for url in urls] return await asyncio.gather(*tasks) urls = [ 'https://api.github.com/users/github' , 'https://api.github.com/users/python' , 'https://api.github.com/repos/python/cpython' ] results = asyncio.run(fetch_all(urls))
常见陷阱与解决方案
陷阱
解决方案
在同步代码中调用async函数
使用 asyncio.run()
阻塞事件循环
使用 run_in_executor()
忘记await
检查所有async函数调用
最佳实践
避免阻塞操作 - 不要在async函数中使用time.sleep()
合理使用并发 - 不是所有场景都需要异步
资源管理 - 使用 async with 管理上下文