← 返回首页
Python3基础教程(八十一)
发表时间:2022-05-14 10:47:47
async/await

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的新语法,要使用新的语法,只需要做两步简单的替换:

  1. 把@asyncio.coroutine替换为async;
  2. 把yield from替换为await。

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。