为什么这个Python生成器/协同程序会丢失一个值?

时间:2017-07-19 06:33:23

标签: python generator coroutine

阅读Python协程,我遇到了这段代码:

def countdown(n):
    print("Start from {}".format(n))
    while n >= 0:
        print("Yielding {}".format(n))
        newv = yield n
        if newv is not None:
            n = newv
        else:
            n -= 1

c = countdown(5)
for n in c:
    print(n)
    if n == 5: c.send(2)

奇怪地输出:

Start from 5
Yielding 5
5
Yielding 3
Yielding 2
2
Yielding 1
1
Yielding 0
0

特别是,它错过了打印3。为什么呢?

引用的问题没有回答这个问题,因为我不是在问send是什么。它将值发送回函数。我问的是,在我发出send(3)之后,为什么下一个产量应该产生3,不会导致for循环打印3。

2 个答案:

答案 0 :(得分:5)

您从未检查过c.send(3)来电的返回值。 实际上,似乎send方法本身推进了生成器, 因此3来电yield c.send(3) def countdown(n): while n >= 0: newv = yield n if newv is not None: n = newv else: n -= 1 c = countdown(5) print(next(c)) print(c.send(3)) print(next(c)) 5 3 2

boolean()

输出结果为:

u'0'

实际上是documented

  

generator.send(值)

     

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

答案 1 :(得分:0)

你在c.send()失败了。您正在比较n == 5,但您没有发送5(在您的函数中是n-1),您正在发送3.例如,它不打印4。

尝试相同的代码,但使用c.send(5),它将从5打印到0。

c = countdown(5)
for n in c:
    print(n)
    if n == 5: c.send(5)
相关问题