gpt4 book ai didi

python - 遍历 asyncio.coroutine

转载 作者:太空狗 更新时间:2023-10-29 20:54:06 25 4
gpt4 key购买 nike

我最近一直在研究 asyncio,虽然我开始对它的工作原理有了直觉,但有些事情我还做不到。我不确定这是因为我的构造有误,还是我尝试做的事情没有意义。

简而言之,我希望能够迭代生成的 asyncio.coroutine。例如,我希望能够执行以下操作:

@asyncio.coroutine
def countdown(n):
while n > 0:
yield from asyncio.sleep(1)
n = n - 1
yield n

@asyncio.coroutine
def do_work():
for n in countdown(5):
print(n)

loop.run_until_complete(do_work())

但是,这会从 asyncio 的内部引发异常。我已经尝试过其他东西,比如 for n in (yield from countdown(5)): ... 但这也给出了类似的不透明运行时异常。

我不能立即明白为什么你不应该做这样的事情,但我已经达到了我理解正在发生的事情的能力的极限。

所以:

  • 如果可以做到这一点,我该怎么做?
  • 如果不可能,为什么不呢?

如果这个问题不清楚,请告诉我!

最佳答案

在 asyncio 协程中,您应该使用 yield from 而永远不要使用 yield。这是设计使然。 yield from 的参数应该是另一个协程或 asyncio.Future 实例。

协程本身的调用应该再次与 yield from 一起使用,例如 yield from countdown(5)

对于您的情况,我建议使用队列:

import asyncio

@asyncio.coroutine
def countdown(n, queue):
while n > 0:
yield from asyncio.sleep(1)
n = n - 1
yield from queue.put(n)
yield from queue.put(None)

@asyncio.coroutine
def do_work():
queue = asyncio.Queue()
asyncio.async(countdown(5, queue))
while True:
v = yield from queue.get()
if v:
print(v)
else:
break

asyncio.get_event_loop().run_until_complete(do_work())

好吧,您可以检查 countdown 产生的值,下面的示例有效。但我认为这是反模式:

  1. 太容易弄得一团糟

  2. 无论如何,您不能使用 itertools 函数组合 countdown 调用。我的意思是 sum(countdown(5))itertools.accumulate(countdown(5))

无论如何,在协程中混合 yieldyield from 的例子:

import asyncio

@asyncio.coroutine
def countdown(n):
while n > 0:
yield from asyncio.sleep(1)
n = n - 1
yield n

@asyncio.coroutine
def do_work():
for n in countdown(5):
if isinstance(n, asyncio.Future):
yield from n
else:
print(n)

asyncio.get_event_loop().run_until_complete(do_work())

关于python - 遍历 asyncio.coroutine,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23709916/

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