为什么这个Pythongenerator/coroutine会丢一个值呢?
Why does this Python generator/coroutine lose a value?
阅读有关 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)
之后,下一个 yield(应该是 3)不会导致 for 循环打印 3。
您在 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)
您从未检查过 c.send(3)
调用的 return 值。
事实上,似乎 send
方法本身推进了生成器,
所以你丢失的 3
是在那个 c.send(3)
电话中 yield
ed 的。
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
实际上是documented:
generator.send(value)
Resumes the execution and “sends” a value into the generator function.
The value argument becomes the result of the current yield expression.
The send() method returns the next value yielded by the generator, or
raises StopIteration if the generator exits without yielding another
value.
阅读有关 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)
之后,下一个 yield(应该是 3)不会导致 for 循环打印 3。
您在 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)
您从未检查过 c.send(3)
调用的 return 值。
事实上,似乎 send
方法本身推进了生成器,
所以你丢失的 3
是在那个 c.send(3)
电话中 yield
ed 的。
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
实际上是documented:
generator.send(value)
Resumes the execution and “sends” a value into the generator function. The value argument becomes the result of the current yield expression. The send() method returns the next value yielded by the generator, or raises StopIteration if the generator exits without yielding another value.