懒惰的迭代器(发电机)与ASYNCIO [英] Lazy iterators (generators) with asyncio
问题描述
我有阻塞,非异步code是这样的:
I have a blocking, non-async code like this:
def f():
def inner():
while True:
yield read()
return inner()
有了这个code调用者可以选择何时停止生成数据的功能。如何改变这种以异步?此解决方案不起作用:
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()
...因为收益
不能在异步DEF
函数使用。如果我删除异步
从内()
签名,我无法使用等待
了。
... because yield
can't be used in async def
functions. If i remove the async
from the inner()
signature, I can't use await
anymore.
推荐答案
如上所述,你不能使用收益
在异步
funcs中。如果你想你要做的创造协程发电机它手动,使用 __ __ aiter
和 __ __ ANEXT
魔术方法:
As noted above, you can't use yield
inside async
funcs. If you want to create coroutine-generator you have to do it manually, using __aiter__
and __anext__
magic methods:
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())
输出:
1
2
3
[Finished in 6.2s]
您还可以看到其他帖子,其中 StopAsyncIteration
用途。
You may also like to see other post, where StopAsyncIteration
uses.
这篇关于懒惰的迭代器(发电机)与ASYNCIO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!