Python 3.5+ 协程 ( coroutines ) 之 async for 表达式

yufei       6 年, 5 月 前       4540

Python 3.5+ 及以上版本中可以使用协程,而在 Python 3.5+ 协程 ( coroutines ) 之协程函数 ( async def ) 篇章中我们也提到,可以在协程函数中使用 async for 表达式

async for 表达式

async for 表达式的语法格式如下

async_for_stmt ::=  "async" for_stmt

async for 表达式用于异步的调用一个迭代器,异步迭代可以在它的 iter 实现中调用异步代码,也可以在 next() 方法中调用异步代码

async for 表达式可以很方便的迭代异步迭代器,就像下面的代码中所展示的一样

async for TARGET in ITER:
    BLOCK
else:
    BLOCK2

上面这段代码类似于

iter = (ITER)
iter = type(iter).__aiter__(iter)
running = True
while running:
    try:
        TARGET = await type(iter).__anext__(iter)
    except StopAsyncIteration:
        running = False
    else:
        BLOCK
else:
    BLOCK2

这段代码中出现了 __aiter__()__anext__(),我们会在稍后的章节中介绍这两个魔法方法

需要注意的是,async for 表达式只能用于在协程函数中,也就是使用 async def 定义的函数中

如果在普通的函数中调用,则会抛出语法异常 SyntaxError

范例

我们写一简单的范例用于输出 1-20 之间所有的奇数

async def echo_odd_of(num):
    async for i in range(1,num):
        if i % 2 == 0:
            print(i, ' ')


echo_odd_of(20)

很不好意思,如果直接这样调用,就会报错

Warning (from warnings module):
  File "/Users/yufei/devops/python/d.py", line 7
    echo_odd_of(20)
RuntimeWarning: coroutine 'echo_odd_of' was never awaited

协程函数的调用的方式一般是这样的

import asyncio

class MyOdd:
    def __init__(self, maximum):
        self.maximum = maximum
        self.step = 0

    def __aiter__(self):
        return self

    @asyncio.coroutine
    def __anext__(self):
        return ( yield from self.do_something())

    @asyncio.coroutine
    def do_something(self):
        while True:
            self.step +=1
            if self.step <= self.maximum and self.step % 2 == 1:
                return self.step
            elif self.step > self.maximum:
                raise StopAsyncIteration


@asyncio.coroutine
async def echo_odd_of(num):
    async for i in MyOdd(num):
        print(i)

loop = asyncio.get_event_loop()
loop.run_until_complete(echo_odd_of(20))
loop.close()

也就是首先要导入 asyncio 模块

import asyncio

然后使用

loop = asyncio.get_event_loop()

创建一个事件循环

最后使用

loop.run_until_complete(echo_odd_of(20))

来运行异步函数,直到函数完成

异步函数完成后,可以使用

loop.close()

来关闭事件循环

需要注意的是,因为使用了异步模式,所以 async for 中的迭代器也必须是异步模式

目前尚无回复
简单教程 = 简单教程,简单编程
简单教程 是一个关于技术和学习的地方
现在注册
已注册用户请 登入
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.