1、 什么是生成器
生成器是执行一个带 yield 语句的函数所返回的对象
def foo():
yield 1
yield 2
f = foo()
其中, type(foo) 是 function, 而 type(f) 是 generaotr
2、 生成器同时是迭代器
生成器对象,实现了 __iter__() 和 next() ,因此,生成器同时是一个 iterable 对象,即“可迭代”对象,可出现在 iterable 对象出现的场合。
3、 为什么需要生成器?
生成器的特点,在于它可以记住运行状态
以 foo() 函数为例,第一次调用的时候,返回 1,并记住已经执行到这里了; 第二次调用的时候,则返回2; 第三次调用的时候,抛出 StopIterator 异常
4、 生成器的本质
对一个函数来说,如果需要记住一些执行状态,那么:
1)、 如果是一个普通函数,状态一定保存在函数体之外,也就是要用到全局变量(或静态全局变量),破坏了封装性。
2)、 如果是一个类的成员函数,则通常将状态保存在类的成员变量中, 封装性很好。
生成器吸取两种方式的长处, 在普通函数的简捷形式的基础之上,又不破坏封装性,并达到了记录状态的目的,符合 python 一贯的简捷高效的风格。
5、 生成器表达式
除了用带 yield 语句的函数以外,还可以通过“生成器表达式”来创建生成器
生成器表达式采用类似“列表解析”的语法,返回的结果是一个生成器
例如:
gen = (x for x in xange(10) if x % 2 == 0)
返回的 gen 就是一个生成器。
“列表解析”, 返回的是一个列表,列表中所有的对象都被创建了; 如果列表很大,就会非常占用内存;
而生成器表达式仅返回一个生成器,因此在内存使用上更有效