生成器的工作原理
只要Python函数的主体中有yield关键字,该函数就是生成器函数。调用生成器函数,返回一个生成器对象。也就是说,生成器函数是生成器工厂。
下面以一个简单的函数说明生成器的行为:
def gen123():yield 1yield 2yield 3print(gen123) # <function gen123 at 0x000002A486B4A200>
print(gen123()) # <generator object gen123 at 0x000002A486AF7270>
for i in gen123():print(i) # 1,2,3g = gen123()
print(next(g)) # 1
print(next(g)) # 2
print(next(g)) # 3
print(next(g)) # StopIteration
可以看出,在函数主体中我们使用了3个yield,输出gen123是函数对象,但是gen123()是个生成器对象。生成器对象实现了Iterator接口,因此生成器对象可以迭代。我们把gen123()赋值给g,因为g是迭代器,所以调用next(g)会获取yield产出下一项,直到所有项产出完以后,抛出StopIteration异常。
生成器函数创建一个生成器对象,包装生成器函数的主体。把生成器对象传递给next()时,生成器函数提前执行函数主体中的下一个yield语句, 返回产出的值,并在函数主体的当前位置暂停。最终,函数的主体返回时,Python创建的外层生成器对象抛出StopIteration异常。
惰性生成器
我们看下面的代码: