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

时间:2014-03-26 01:09:44

标签: 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)

这引发了一个例外:

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

虽然错误很明显,但感觉这应该是可能的。我从来没有想过一个有用的,逼真的递归协程应用程序,所以我不是在寻找特定问题的答案。除了可能的实施难度之外,有没有理由认为这是不可能的?

1 个答案:

答案 0 :(得分:4)

这是不可能的,因为要使send起作用,协程必须等待输入。 yield暂停协同程序,并sendnext取消暂停。如果生成器正在调用send,则无法同时暂停并等待输入。

如果你能send到一个未被取消的协程,那么语义会变得非常奇怪。假设rc.send(rc)行有效。然后send将从它停止的地方继续执行协同程序,这就是发送调用......但是send没有返回的值,因为我们没有达到收益。

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