理解python yield

时间:2021-04-05 10:10:42

python源代码中经常会有使用yield,带有yield的函数是generator(生成器),它返回是一个迭代值,下面我们分析yield是什么原理,有什么好处?

首先,我们写一个简单的斐波那契数列前n项值得方法:

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

函数输出1  1  2  3  5  没有问题,但是该方法没有返回值,复用性太差了,我们希望得到有返回结果的方法。

修改如下:

def fab(max):
n,a,b=,,
result=[]
while n<max:
result.append(b)
a,b=b,a+b
n=n+
return result
print fab()
input()

返回[1,1,2,3,5]的list,这样我们就可以方便的用它的结果了,但是当max很大时,对内存是一个很大的开销,并不是一个好的方法,怎么办呢?这就要用到迭代器的知识了,返回一个迭代变量是更好的选择。

例如 for i in range(100):pass  会导致生成一个100个元素的list;

  for i in xrange(100):pass  不会产生100个元素的list,而是每次返回一个iterable对象,只有上一个数据用完之后才生成下一个,每次只返回一个,所以减小了内存开销。

利用iterable我们可以把fab()方法写成一个支持iterable的class,如下:

class Fab(object):
def __init__(self,max):
self.max=max
self.n,self.a,self.b=,,
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+
return r
raise StopIteration()
fab=Fab()
for n in fab:
print n
input()

这样就实现了迭代器的返回方法,但是代码太多,不够简洁,这时候yield就用上了。

def fab(max):
n,a,b=,,
while n<max:
yield b
a,b=b,a+b
n=n+
for i in fab():
print i
input()

这样就实现了。

yeild的原理:一个带有yield的函数就是一个generator生成器,和普通的函数不一样。只有调用next()函数的时候才会执行函数语句,在for循环中会自动调用next()方法。函数执行过程中遇到一个yield会中断一次,返回一个迭代值,函数保存自己的变量和状态,下次迭代时(也就是下次next()的时候)从yield下一条语句继续执行(这个性质很重要),函数恢复之前状态,直到遇到下一个yield返回迭代值,这样循环。

可以用

f=fab(5)

fab.next()不断测试来分析它的原理。