通过关键字 yield,可以从生成器中产生值,并返回。我们可以将生成器作为一个生产者来使用。
在协程中,通过使用关键字 yield,还可以让具有 yield 的程序接收值。此时函数作为消费者,消费我们传入(send)的值。
在协程中,可以把 yield 作为右值来用。在 foo 函数中,我们这样写:
n = yield
可以通过 send 方法来向 foo 函数发送值,这时,发送的值被 foo 接收,并存到 n 里。
n 中的值可以在 foo 函数中使用
这样,yield 作为右值来使用,就使得 foo 函数变成了一个消费者。
我们知道,yield 关键字用于向调用者返回值。
当作为右值来使用的时候,yield 的作用仍然不变,仍然可以向调用者返回值。
当在 foo 函数中也可以这样写:
n = yield c
这样实际上将 foo 函数变成了一个能消费我们传给它的值的生成器。
n 的值与 c 的值无关。如果非要说相关,只是他们出现在了同一行里,对 yield 有不同的解读罢了。
注意区分:n 的值是我们
send
的值,c 的值是保留(hold)的
上一步的值
。
c 的值在什么时候返回呢?只要调用者使用 next(),或者之前给 c 赋过值,现在又走到 yield c 这里了,那么就返回了。
试着理解下面这段代码:
- 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
- c = countdown(5)
- for n in c:
- print n
- if n == 5:
- c.send(3)
注意这样一个基本事实,就能知道输出是什么:
for ... in ... 是通过调用 next() 方法来获取下一个值的,而调用 next() 方法,相当于 send(None)
输出是:
- Counting down from 55210
协程的启动:
c.next()
c.send(None)
协程的关闭:
c.close()
来源: http://www.bubuko.com/infodetail-2446844.html