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
中的迭代器也必须是异步模式
目前尚无回复