知识背景:
1 调用一个普通的Python函数时,一般是从函数的第一行代码开始执行,结束于return语句、异常或者函数结束(可以看作隐式的返回None)
2 一旦函数将控制权交还给调用者,就意味着全部结束。函数中做的所有工作以及保存在局部变量中的数据都将丢失
3 再次调用这个函数时,一切都将从头创建。
4 如上流程其实是调用一个标准函数的过程,而且一个标准函数只能返回一个值
需求来了:
创建能产生一个序列的函数
此时出现了关键字 yield应用而生:
return: 函数将执行代码的控制权返回给函数调用者
yield: 控制权的转移是临时和自愿的,我们的函数将来还会收回控制权
带有yield关键字的函数叫做生成器,这个生成器就完成了返回一个序列的函数的目的。
那么生成器函数和普通标准函数区别在哪里呢?
1 除了有一个关键词yield之外,生成器函数的写法和普通函数一样
2 生成器函数也可以有return
3 生成器函数返回生成器的迭代器,俗称生成器。
4 可以使用方法 next()从生成器中得到下一个值
5 每次生成器被调用时,其内部使用yield返回数值给调用者,并记录当前执行状态,
也就是说 yield是专门给生成器使用的特殊return
案例扩展:
def fab(max):
n, a, b = 0, 0, 1
while n < max:
yield b
# print b
a, b = b, a + b
n = n + 1
>>> for n in fab(5):
... print n
解释如下:
1 调用时 返回迭代器(此时函数体是不会执行的,只有在调用返回的迭代器next()方法或者用for循环遍历时--for循环会自动调用迭代器的next(),并)
2 for的每一次循环,会执行fab函数体,即执行迭代器的一次迭代,迭代的内容是执行到函数体yield,返回迭代值。
3 执行for的第二次循环,执行fab函数,即执行第二次迭代,第二次迭代是从上次迭代执行中断处yield b的下一个语句继续执行,然后执行到下一个yield b返回迭代值,再次中断。
4 yield将每次中断做了记录,把一个函数改写为一个 generator 并持有了迭代能力
5 区分 fab 和 fab(5),fab 是一个 generator function,而 fab(5) 是调用 fab 返回的一个 generator,好比类的定义和类的实例的区别
可以使用来验证上述几条:
>>> f = fab(5)
>>> f.next() 这里迭代器的next() 和 for n in fab(5): 中执行每一次循环的执行效果是一样的,我们用 f.next()来验证上述执行的1,2,3步骤
1
>>> f.next()
1
>>> f.next()
2
>>> f.next()
3
>>> f.next()
5
参考链接: http://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/