gpt4 book ai didi

python - 将异步生成器转换为同步生成器

转载 作者:行者123 更新时间:2023-12-05 04:32:51 24 4
gpt4 key购买 nike

假设我们有一个返回生成器的原始 API(它实际上是一种机制,可以从服务器带来页面/结果 block ,同时向用户提供一个简单的生成器,并让他一个一个地迭代这些结果。为简单起见:

# Original sync generator
def get_results():
# fetch from server
yield 1
yield 2
# fetch next page
yield 3
yield 4
# ....

现在需要实现 API 的异步版本,但是我们也需要保持旧 API 的可操作性。这就是事情变得复杂的地方,我们有点想将异步生成器转换为同步生成器,但我找不到一种优雅的方法来做到这一点。到目前为止我能做的最好的工作是“首先将所有结果提取到一个列表中,然后在该列表上提供一个假的同步生成器”。哪种违背了目的:

# Async generator
async def get_results_async():
# await fetch from server
yield 1
yield 2
# await fetch next page
yield 3
yield 4
# ....


# Backward compatible sync generator
def get_results():

async def gather_all_results():
res = []
async for i in get_results_async():
res.append(i)
return res

res = asyncio.run(gather_all_results())
for i in res:
yield i

有没有更好、更优雅的方法来做到这一点,而无需在返回之前获取所有结果?

谢谢

最佳答案

由于 asyncio 具有传染性,因此很难编写优雅的代码将 asyncio 代码集成到旧代码中。对于上面的场景,流畅的代码好一点,但我认为它不够优雅。

async def get_results_async():
# await fetch from server
yield 1
yield 2
# await fetch next page
yield 3
yield 4
# ....


# Backward compatible sync generator
def get_results():
gen = get_results_async()
while True:
try:
yield asyncio.run(gen.__anext__())
except StopAsyncIteration:
break

而且您可以重复使用您的事件循环,而不是创建一个新的。

async def get_results_async():
# await fetch from server
yield 1
yield 2
# await fetch next page
yield 3
yield 4
# ....

# loop that you save in somewhere.
loop = asyncio.get_event_loop()

# Backward compatible sync generator
def get_results():
gen = get_results_async()
while True:
try:
yield loop.run_until_complete(gen.__anext__())
except StopAsyncIteration:
break

关于python - 将异步生成器转换为同步生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71580727/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com