值在python生成器/协同程序中丢失

时间:2013-08-01 09:48:01

标签: python iteration generator coroutine

我在看http://www.dabeaz.com/coroutines/,我觉得这很有趣,但在一个例子中有一种我不理解的行为。

bogus.py示例中,此处报告

# bogus.py
#
# Bogus example of a generator that produces and receives values
def countdown(n):
    print "Counting down from", n
    while n >= 0:
        newvalue = (yield n)
        # If a new value got sent in, reset n with it
        if newvalue is not None:
            n = newvalue
        else:
            n -= 1

# The holy grail countdown
c = countdown(5)
for x in c:
    print x
    if x == 5:
        c.send(3)

生成的数字序列是5,2,1,0,我无法理解数字3消失的位置:在send(3)之后,变量n被正确设置,但是第二次执行yield时,看起来值3只是非屈服于for循环。

有人可以澄清为什么会这样吗?

1 个答案:

答案 0 :(得分:3)

3已从.send()返回,但已被丢弃。生成器生成53210;但由于3已返回.send()来电,因此您看不到该值已打印。 for循环永远不会看到它。

这是怎么回事:

  • 第一次for循环调用生成器上的next()时,代码会前进,直到5生成。
  • x == 5True,因此调用了c.send(3)。代码通过生成器函数前进,newvalue设置为3
  • 生成器暂停,它现在有控制权。生成器运行while循环并返回(yield n)表达式。 3屈服了。它成为c.send(3)的返回值。返回值在这里被丢弃。
  • for循环继续,再次调用next()。再次继续生成器,yield返回None,循环到n -= 1并产生2
  • for循环继续在生成器上调用next()1并生成0,生成器结束。

来自generator.send() documentation

的qouting
  

恢复执行并将值“发送”到生成器函数中。 value参数成为当前yield表达式的结果。 send()方法返回生成器产生的下一个值,如果生成器退出而没有产生其他值,则引发StopIteration

强调我的。