【问题标题】:Value get lost in python generator/coroutine值在 python 生成器/协程中丢失
【发布时间】:2013-08-02 04:09:50
【问题描述】:

我正在查看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 循环。

有人能解释一下为什么会这样吗?

【问题讨论】:

    标签: python iteration generator coroutine


    【解决方案1】:

    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()10 产生,生成器结束。

    转自generator.send() documentation:

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

    强调我的。

    【讨论】:

    • 太好了,谢谢!在您的第三点中,我错过了一个事实,即send 实际上与next 相似,因此具有来自yield 的返回值。
    • 从规范中添加 (pep-0342) 2. 为生成器迭代器添加一个新的 send() 方法,该方法恢复生成器并“发送”一个值,该值成为当前产量表达式的结果. send() 方法返回生成器产生的下一个值,或者如果生成器退出而没有产生另一个值,则引发 StopIteration。
    • 第3步我也有点困惑。当 n == 5 时,产生 5 并打印它。然后,c.send(3) 触发 yield 3 作为返回值返回给 c.send() 并将值 3 赋给 newvalue 如果我的语句为 True,那么为什么当 n == 3 时继续下一个循环命中 newvalue = (yield n) 而不产生值 n 但说值 n == 3 被丢弃?
    • @rickhau:你到底有什么困惑?
    • 我对为什么在 c.send(3) 之后的 (yield n) 的下一个循环中丢弃该值感到困惑,我还尝试在 yield 语句之后立即打印出 newvalue:@987654363 @5 ` -> newvalue = 3` ` -> newvalue = None` 我也很困惑,为什么那里有两次迭代?是send()函数引起的吗?
    猜你喜欢
    • 2017-12-24
    • 2017-09-02
    • 2011-08-22
    • 1970-01-01
    • 2016-02-02
    • 2015-10-31
    • 2023-03-05
    • 2015-12-11
    • 1970-01-01
    相关资源
    最近更新 更多