Coroutine的奇怪行为

时间:2012-08-06 08:38:51

标签: python coroutine

我正在学习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”)

while,

@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. 我知道每个协程功能都与子程序不同。

    但是,我认为,在打印机功能结束后,应该终止程序而不返回发件人。

    但确实如此。这不意味着发送者优于打印机吗?那么子程序和协程之间有什么区别。

  4. 感谢阅读,如果你让我高兴,我真的很感激。)

2 个答案:

答案 0 :(得分:5)

当生成器(如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函数,然后执行

print "I'm sender"

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

它不会改变StopIteration行为。

答案 1 :(得分:2)

这是对协同程序的一个非常好的介绍:

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

特别是,您可以查看:

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

和(例如@coroutine实现):

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