# 初步解析python中的yield函数的用法

def fab(max):
n, a, b = 0, 0, 1
while n < max: print b a, b = b, a + b n = n + 1

>>> fab(5)
1
1
2
3
5

def fab(max):
n, a, b = 0, 0, 1
l = []
while n < max: l.append(b) a, b = b, a + b n = n + 1 return l

>>> for n in fab(5):
… print n

1
1
2
3
5

for i in range(1000): pass

for i in xrange(1000): pass

class fab(object):
def __init__(self, max):
self.max = max
self.n, self.a, self.b = 0, 0, 1
def __iter__(self):
return self
def next(self):
if self.n < self.max: r = self.b self.a, self.b = self.b, self.a + self.b self.n = self.n + 1 return r raise stopiteration()

fab 类通过 next() 不断返回数列的下一个数，内存占用始终为常数：

>>> for n in fab(5):
… print n

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

>>> f = fab(5)
>>> f.next()
1
>>> f.next()
1
>>> f.next()
2
>>> f.next()
3
>>> f.next()
5
>>> f.next()
traceback (most recent call last):
file “”, line 1, in
stopiteration

yield 的好处是显而易见的，把一个函数改写为一个 generator 就获得了迭代能力，比起用类的实例保存状态来计算下一个 next() 的值，不仅代码简洁，而且执行流程异常清晰。

>>> from inspect import isgeneratorfunction
>>> isgeneratorfunction(fab)
true

>>> import types
>>> isinstance(fab, types.generatortype)
false
>>> isinstance(fab(5), types.generatortype)
true

fab 是无法迭代的，而 fab(5) 是可迭代的：

>>> from collections import iterable
>>> isinstance(fab, iterable)
false
>>> isinstance(fab(5), iterable)
true

>>> f1 = fab(3)
>>> f2 = fab(5)
>>> print ‘f1:’, f1.next()
f1: 1
>>> print ‘f2:’, f2.next()
f2: 1
>>> print ‘f1:’, f1.next()
f1: 1
>>> print ‘f2:’, f2.next()
f2: 1
>>> print ‘f1:’, f1.next()
f1: 2
>>> print ‘f2:’, f2.next()
f2: 2
>>> print ‘f2:’, f2.next()
f2: 3
>>> print ‘f2:’, f2.next()
f2: 5

return 的作用

def read_file(fpath):
block_size = 1024
with open(fpath, ‘rb’) as f:
while true:
block = f.read(block_size)
if block:
yield block
else:
return

Posted in 未分类