[英]Lazy iterators (generators) with asyncio
I have a blocking, non-async code like this: 我有一个像这样的阻塞,非异步代码:
def f():
def inner():
while True:
yield read()
return inner()
With this code the caller can choose when to stop the function to generate data. 使用此代码,调用者可以选择何时停止函数以生成数据。 How to change this to async?
如何将此更改为异步? This solution doesn't work:
此解决方案不起作用:
async def f():
async def inner():
while True:
yield await coroutine_read()
return inner()
... because yield
can't be used in async def
functions. ...因为
yield
不能用于async def
函数。 If i remove the async
from the inner()
signature, I can't use await
anymore. 如果我从
inner()
签名中删除async
,我就不await
使用await
了。
Upd: UPD:
Starting with Python 3.6 we have asynchronous generators and able to use yield
directly inside coroutines. 从Python 3.6开始,我们有异步生成器,并且能够直接在协程内使用
yield
。
As noted above, you can't use yield
inside async
funcs. 如上所述,您不能在
async
funcs中使用yield
。 If you want to create coroutine-generator you have to do it manually, using __aiter__
and __anext__
magic methods: 如果你想创建协
__aiter__
器,你必须使用__aiter__
和__anext__
魔术方法手动完成:
import asyncio
# `coroutine_read()` generates some data:
i = 0
async def coroutine_read():
global i
i += 1
await asyncio.sleep(i)
return i
# `f()` is asynchronous iterator.
# Since we don't raise `StopAsyncIteration`
# it works "like" `while True`, until we manually break.
class f:
async def __aiter__(self):
return self
async def __anext__(self):
return await coroutine_read()
# Use f() as asynchronous iterator with `async for`:
async def main():
async for i in f():
print(i)
if i >= 3:
break
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Output: 输出:
1
2
3
[Finished in 6.2s]
You may also like to see other post , where StopAsyncIteration
uses. 您可能还希望看到
StopAsyncIteration
使用的其他帖子 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.