简体   繁体   English

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

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM