4

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

@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("你好")

尽管,

@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。

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

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

4

2 回答 2

5

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

当 Python 执行时

coru.send("hello")

它跳到

tmp = (yield)

并将“你好”分配给tmp. 然后它执行下一行:

print tmp

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

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

tmp = (yield)

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

print "I'm sender"

yield from语法的目的是更容易将生成器(旨在与sendand一起使用throw)重构为子生成器。请参阅 PEP380和Python3中的新增功能

它不会改变 StopIteration 行为。

于 2012-08-06T08:57:37.703 回答
2

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

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

特别是,您可以查看:

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

和(示例@coroutine 实现):

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

于 2012-08-06T09:00:25.813 回答