Python 中的 async/await 语法是 Python 异步编程的核心,从 Python 3.5 版本开始引入,使得编写异步代码变得更加简单和直观。
基本概念
- 异步编程:允许程序在等待操作完成时继续执行其他任务的编程范式,非常适合处理 I/O 密集型任务,如网络请求、文件读写等。
async函数 :使用async def定义的函数。这种函数被调用时不会立即执行,而是返回一个awaitable对象。await表达式 :用于暂停异步函数的执行,直到等待的awaitable对象完成,释放执行权给事件循环。
使用 async/await
定义异步函数
使用 async def 定义一个异步函数,函数内部可以使用 await 来调用其他异步函数或执行异步操作。
python
import asyncio
async def fetch_data():
print("开始获取数据...")
await asyncio.sleep(2) # 模拟 I/O 操作
print("数据获取完成")
return {'data': 123}
调用异步函数
异步函数需要在事件循环中调用。不能直接像调用普通函数那样调用异步函数。
python
async def main():
data = await fetch_data()
print(data)
# Python 3.7+
asyncio.run(main())
注意点
- 事件循环 :理解异步编程的关键是要明白代码是如何被事件循环处理的。
asyncio.run()函数负责运行主函数,并管理事件循环。 await的使用 :只能在async函数内部使用await关键字。- 阻塞操作 :避免在异步函数中使用阻塞调用。如果需要执行阻塞操作,应该使用适当的异步库,或者使用
loop.run_in_executor()将阻塞调用委托给线程池或进程池。 - 并发执行 :使用
asyncio.gather()可以并发运行多个异步任务。
示例:并发执行异步函数
python
async def fetch_data(task_number):
print(f"任务 {task_number}: 开始获取数据...")
await asyncio.sleep(2) # 模拟 I/O 操作
print(f"任务 {task_number}: 数据获取完成")
return {f'task_{task_number}': 123}
async def main():
results = await asyncio.gather(
fetch_data(1),
fetch_data(2),
fetch_data(3),
)
for result in results:
print(result)
asyncio.run(main())
这个示例展示了如何并发执行三个异步任务,并收集它们的结果。asyncio.gather() 是并发运行多个协程的推荐方式,因为它同时启动所有协程,并等待它们全部完成。
async/await 使得异步编程在 Python 中变得非常直观和易于理解。只要记住上述的基本概念和注意点,你就能有效地利用 Python 的异步编程特性了。