【问题标题】:strange behavior of Coroutine协程的奇怪行为
【发布时间】:2012-08-06 08:38:51
【问题描述】:

我正在学习 Coroutine,但它的工作方式很奇怪,我无法理解...... 这是来源

@coroutine
def printer():
    tmp=(yield)
    print tmp

def sender(coru):
    coru.send("hello")
    print "I'm sender"

if __name__=="__main__":
    coru=printer()
    sender(coru)
    print "I'm master"

表演

你好

StopItertationError @ coru.send("hello")

同时,

@coroutine
def printer():
          while 1:
               tmp=(yield)
               print tmp

def sender(coru):
    coru.send("hello")
    print "I'm sender"

if __name__=="__main__":
    coru=printer()
    sender(coru)
    print "I'm master"

表演

你好

我是发件人

我是大师

正确。

所以我想知道

  1. 为什么协程总是使用循环以及为什么第一个示例会出现错误

  2. 我在 3.3 版中听说过“yield from”语法。这对第一个工作有帮助吗?

  3. 我知道每个协程函数的工作方式与子程序不同。

    但是,我认为,在Printer函数结束后,程序应该终止而不返回Sender。

    但确实如此。不是说发件人优于打印机吗?那么子程序和协程有什么区别呢。

感谢您的阅读,如果您能启发我,我真的很感激:)

【问题讨论】:

  • 关于@coroutine。它只是自动化 func.next() 以使协程准备就绪的包装器

标签: python coroutine


【解决方案1】:

当生成器(如printer)结束时,它会引发 StopIteration 异常。

当 Python 执行时

coru.send("hello")

跳转到

tmp = (yield)

并将“hello”分配给tmp。然后它执行下一行:

print tmp

然后生成器结束,从而引发StopIteration 异常。

另一方面,如果您不允许printer 结束(通过使用while 1 循环),则永远不会引发StopIteration 异常。而是继续执行(在printer 中),直到到达下一个yield 表达式:

tmp = (yield)

send 方法返回yield 表达式的值(在本例中为None)。至此,Python再次返回sender函数并next执行

print "I'm sender"

yield from 语法的目的是更容易将生成器(旨在与sendthrow 一起使用)重构为子生成器。 See PEP380What's New in Python3

它不会改变 StopIteration 行为。

【讨论】:

    【解决方案2】:

    这是一个很好的协程介绍:

    http://www.dabeaz.com/coroutines/

    具体来说,你可以看看:

    http://www.dabeaz.com/coroutines/grep.py

    和(@coroutine 实现示例):

    http://www.dabeaz.com/coroutines/coroutine.py

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-06
      • 1970-01-01
      • 2019-06-25
      • 1970-01-01
      相关资源
      最近更新 更多