为什么不能递归调用 Python 协程?

gen*_*ens 3 python recursion generator coroutine

我一直在使用 Python 协程而不是线程,并取得了一些成功。我突然想到我可能会用到一个知道自己的协程,所以它可以给自己发送一些东西。我发现这是不可能的(无论如何在 Python 3.3.3 中)。为了测试,我写了以下代码:

def recursive_coroutine():
    rc = (yield)
    rc.send(rc)

reco = recursive_coroutine()
next(reco)
reco.send(reco)
Run Code Online (Sandbox Code Playgroud)

这引发了一个异常:

Traceback (most recent call last):
  File "rc.py", line 7, in <module>
    reco.send(reco)
  File "rc.py", line 3, in recursive_coroutine
    rc.send(rc)
ValueError: generator already executing
Run Code Online (Sandbox Code Playgroud)

虽然错误很明显,但感觉这应该是可能的。我从来没有想出一个有用的、现实的递归协程应用程序,所以我不是在寻找特定问题的答案。除了实施困难之外,是否还有其他原因无法实现?

use*_*ica 5

这是不可能的,因为send要工作,协程必须等待输入。yield暂停协程,send然后next取消暂停。如果生成器正在调用send,则不能同时暂停和等待输入。

如果您可以send使用未暂停的协程,语义会变得非常奇怪。假设那条rc.send(rc)线有效。然后send将从它停止的地方继续执行协程,即发送调用......但没有send返回值,因为我们没有达到产量。

假设我们返回一些虚拟值并继续。然后协程将执行到下一个yield. 在那个时候,会发生什么?执行是否倒带以便send返回产生的值?是否yield丢弃该值?控制流去哪里了?没有好的答案。