async/await是协程的语法糖,使协程之间的调用变得更加清晰。
1.python常见的函数类型
# 1. 普通函数 FunctionType
def function():
return 1
# 2. generator function :GeneratorType
def generator():
yield 2 # 生成器
# async修饰将普通函数和生成器函数包装成异步函数和异步生成器
# 3. 异步函数(协程) :CoroutineType
async def async_function():
return 3
# 4. 异步生成器 : AsyncGeneratorType
async def async_function():
yield 4
2.async/await
为了简化并更好地标识异步IO,从Python 3.5开始引入了新的语法async和await,可以让coroutine的代码更简洁易读。
注意,async和await是针对coroutine的新语法,要使用新的语法,只需要做两步简单的替换:
async/await是协程的语法糖,使协程之间的调用变得更加清晰:
实例:
模拟三台洗衣机洗三批衣服, 并统计这三批衣服洗完花费的总时间。
# -*- coding: utf-8 -*-
# @Time : 2022/5/17 8:51
# @File : async_await_demo.py
# @Software : PyCharm
from time import sleep, time
def demo():
"""
这是最终我们想要的实现.
"""
import asyncio # 引入 asyncio 库
async def washing1():
#第一台洗衣洗完要花费3分钟。
await asyncio.sleep(3) # 使用 asyncio.sleep(), 它返回的是一个可等待(awaitable)的对象
print('washer1 finished')
async def washing2():
#第二台洗衣洗完要花费2分钟。
await asyncio.sleep(2)
print('washer2 finished')
async def washing3():
#第三台洗衣洗完要花费5分钟。
await asyncio.sleep(5)
print('washer3 finished')
"""
事件循环机制分为以下几步骤:
1. 创建一个事件循环
2. 将异步函数加入事件队列
3. 执行事件队列, 直到最晚的一个事件被处理完毕后结束
4. 最后建议用 close() 方法关闭事件循环, 以彻底清理 loop 对象防止误用
"""
tasks = [
washing1(),
washing2(),
washing3(),
]
asyncio.run(asyncio.wait(tasks))
"""
最终的打印效果:
washer2 finished
washer1 finished
washer3 finished
elapsed time = 5.126561641693115
(毕竟切换线程也要有点耗时的)
"""
if __name__ == '__main__':
# 为验证是否真的缩短了时间, 我们计个时
start = time()
demo() # 需花费5秒多一点点
end = time()
print('elapsed time = ' + str(end - start))
运行结果:
washer2 finished
washer1 finished
washer3 finished
elapsed time = 5.153118371963501
小结: Python从3.5版本开始为asyncio提供了async和await的新语法;注意新语法只能用在Python 3.5以及后续版本,如果使用3.4版本,则仍需使用asyncio提供的@asyncio.coroutine。