参考链接:
http://blog.163.com/l_greatsea/blog/static/2049860442013220113640476/
http://blog.chinaunix.net/uid-11989741-id-3389226.html
前一篇文章主要讲解yield的用法,后面文章主要讲了使用send的一个例子。但是之前理解起来一直困难。代码如下:
- def countdown(n):
- print "Counting down from", n
- while n >= 0:
- newvalue = yield n
- 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)
结合两篇文章,我将这个带yield的函数分成4部分。
红色部分,yield之前。
绿色部分,yield将要返回的表达式。
紫色部分,yield语句。
黄色部分,yield之后的部分。
根据概念,我没每调用一次generator的next()方法都会返回一次yield表达式的值。yield本身返回None,但是send(value)可以给yield赋值。
我们来看下面的运行过程:
c = countdown(5)
这句产生一个迭代器。
在for循环第一次print x 。将调用一次c.next()。
按照我的理解这第一次c.next()会运行红色部分代码,然后将绿色部分”n“这个值返回。所以第一次会打印5.(注意:这个时候想像成没有运行紫色部分,yield这个语句)
接下来运行if判断的语句。c.send(3)。从之前的两篇文章中可以得出结论:send本身算是一个next,但是它有一个功能就是能将yeild有返回值,值就是send的这个value。
所以,运行 ‘newvalue = yield’ 就相当于运行了newvalue=3.然后直接往下执行,直到下一次有遇到yield n。返回n值。然后进入下一次for循环的c.next().
下一次c.next()的时候yield语句(或者说是表达式)返回None,进入n -= 1。然后在下一个yield之前返回n值。以此类推。
我觉得这样比文章2中的解释好理解的多。欢迎交流。shezfp@qq.com