[英]Lazy iterators (generators) with asyncio
我有一個像這樣的阻塞,非異步代碼:
def f():
def inner():
while True:
yield read()
return inner()
使用此代碼,調用者可以選擇何時停止函數以生成數據。 如何將此更改為異步? 此解決方案不起作用:
async def f():
async def inner():
while True:
yield await coroutine_read()
return inner()
...因為yield
不能用於async def
函數。 如果我從inner()
簽名中刪除async
,我就不await
使用await
了。
UPD:
從Python 3.6開始,我們有異步生成器,並且能夠直接在協程內使用yield
。
如上所述,您不能在async
funcs中使用yield
。 如果你想創建協 __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())
輸出:
1
2
3
[Finished in 6.2s]
您可能還希望看到StopAsyncIteration
使用的其他帖子 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.