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

标签 python asynchronous python-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

最佳答案

更新:

从 Python 3.6 开始,我们有 asynchronous generators并且能够在协程中直接使用 yield


如上所述,您不能在 async 函数中使用 yield。如果你想创建 coroutine-generator你必须手动完成,使用 __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]

您可能还想看看 other post ,其中 StopAsyncIteration 使用。

关于python - 带有 asyncio 的惰性迭代器(生成器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37280141/

相关文章:

python - aiohttp:如何将sub_app添加到sub_app?

python - 在这里可以接受抑制 `asyncio.CancelledError` 吗?

python - 为字符串列表中的子字符串实现更高效的 Python 算法

javascript - 如果用户中止连接到服务器(连接时刷新、关闭浏览器等),如何停止执行所有功能(多个异步等)

c# - 如何向 HttpClient.GetAsync 返回的任务添加更多详细信息

javascript - 如何在同步函数中等待 JavaScript 中的异步调用?

python - 异步: Why is awaiting a cancelled Future not showing CancelledError?

python - 如何将两个列表与第三个列表进行比较,如果存在匹配,则将它们分组到Python中的嵌套列表中?

python - Pyschools 主题 13 Q 9 csv.writer

func 中的 Python 局部变量