Python 基于产量的协同规划是真正的协同规划吗?

Python 基于产量的协同规划是真正的协同规划吗?,python,coroutine,Python,Coroutine,我实现greenlet API只是为了练习 from greenlet import greenlet def test1(): print 12 gr2.switch() print 34 def test2(): print 56 gr1.switch() print 78 gr1 = greenlet(test1) gr2 = greenlet(test2) gr1.switch() 这是我的乱码 def test1(): tm

我实现greenlet API只是为了练习

from greenlet import greenlet

def test1():
    print 12
    gr2.switch()
    print 34

def test2():
    print 56
    gr1.switch()
   print 78

gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()
这是我的乱码

def test1():
    tmp1=yield
    print 12
    try:
        gv2.send(1)
    except StopIteration:
        pass
    tmp1=yield
    print 34

def test2():
    tmp2=yield
    print 56
    try:
        gv2.send(1)
    except StopIteration:
        pass
    tmp1=yield
    print 78

gv1=test1()
gv1.next()
gv2=test2()
gv2.next()

gv1.send(1)
显示

12
56
Traceback (most recent call last):
  File "prog.py", line 26, in <module>
    gv1.send(1)
  File "prog.py", line 5, in test1
    gv2.send(1)
  File "prog.py", line 15, in test2
    gv2.send(1)
ValueError: generator already executing
12
56
回溯(最近一次呼叫最后一次):
文件“prog.py”,第26行,在
gv1.发送(1)
test1中第5行的文件“prog.py”
gv2.发送(1)
test2中第15行的文件“prog.py”
gv2.发送(1)
ValueError:生成器已在执行
所以我不知道我猜对了

但是看起来在test1将“1”发送到test2之后,它仍然有一些东西

与gevent不同,没有控制流切换。test1仍然具有流

如果不是,我不明白greenlet可以做什么,但python“协同程序”不存在

我的问题是

  • pythoncoroutine(基于收益率)是真实的吗(将它与其他东西进行比较…lisp、ruby和c)
  • 如果正确的话,你能给一些关于spagetti代码的提示吗

  • test2()
    的生成器实例正在向自身发送一个值

    def test2():
        tmp2=yield
        print 56
        try:
            gv2.send(1) # this is the offending line
        except StopIteration:
            pass
        tmp1=yield
        print 78
    
    send()
    将恢复生成器,但只要在
    test2()中执行代码,它就已经在运行了。这就是它呕吐的原因

    是否要执行:
    gv1.send(1)
    ?这也行不通

    原因如下:

    • 当前情况:在
      gv1之前。在示例的最后发送(1)
      • gv1处于休眠状态
      • gv2处于休眠状态
    • gv1.send(1)
      被调用,这将继续
      gv1
    • gv1
      进入
      gv2.发送(1)
    • 这将继续
      gv2
    • gv2
      进入
      gv1。发送(1)
    • gv1
      正在恢复,但是,
      gv1
      自上次恢复以来未达到
      yield
      语句。因此,它仍在运行,这就是它也会抛出的原因
    本质上,差异可以概括如下:

    • greenlet彼此共享一个固有的连接:
      .switch()
      暂停当前正在执行的greenlet,但会继续
    • 另一方面,发电机彼此完全独立。不存在执行生成器的共享上下文。
      • yield
        将“暂停”生成器
      • next()
        /
        send()
        将恢复暂停的生成器,在运行的生成器上调用它们将导致异常

    为什么要访问
    gv2
    (它代表了
    test2
    的一个特定实例)?生成器
    test2()
    应该是自包含的,并且不对其使用方式进行任何假设。如果您决定从其他范围调用生成器,该怎么办?不管怎样,向自己发送价值观是没有意义的:你已经拥有了这些价值观。

    你在寻找什么“提示”?关于到底是什么?哦,这只是个错误,我打算使用“gv1.send(1)”,而我的测试代码实际上就是它。我想知道为什么‘gv1.send(1)’不起作用。关于如何使用基于收益率的‘coroutine’@成功地实现这个例子的“提示”来自未来,这篇文章解释了为什么不起作用;)请参阅
    “原因如下:”
    是的,我读了它,现在明白了异常出现的原因。那么,如果你不介意的话,有没有办法实现第一个呢?如果Python能够做到这一点,那么它将与两个协同程序交互,看起来非常有用it@from__future__您可以创建第三个生成器,在两个生成器之间来回洗牌数据。