簡體   English   中英

帶有asyncio的惰性迭代器(生成器)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM