Python中的生成器

40 阅读2分钟

迭代器模式用来惰性获取数据项,按照需要,一次获取一个数据项。

在python中,用 yield 关键字来构建生成器。作用和迭代器一样。

可迭代对象、迭代器和生成器

什么是可迭代对象?

根据鸭子理论:只要实现了 __iter__ 方法的 或者 实现了 __getitem__,并且index 从0开始的,都是可迭代对象。

根据白鹅理论:只要实现了__iter__ 方法的就是可迭代对象

鸭子理论相较于白鹅理论,更为灵活。

因为在Python中,所有的序列都实现了__getitem__ 方法,所以,Python中所有的序列都是可迭代对象

什么是迭代器

  • 用于从集合中取出元素
  • Python 从 可迭代对象中获取迭代器
  • iter() 可以获取迭代器

标准的定义是

  • 实现了无参数的__next__() 方法
  • 如果没有元素了,就抛出 StopIteration 异常
  • 实现了__iter__() 方法,并且返回实例自身

什么是生成器函数和生成器对象

只要Python 函数的定义体中有yield 关键字,该函数就是生成器函数

调用生成器函数时,会返回一个生成器对象。

生成器函数的工作原理 和 使用

生成器函数的工作原理

  1. 生成器函数会创建一个生成器对象,包装生成器函数的定义体
  2. 把生成器对象传给next()函数时,生成器函数会向前,执行函数定义体中的下一个 yield 语句,返回产出的值,并在函数定义体的当前位置暂停
  3. 函数的定义体返回时,外层的生成器对象会抛出 StopIteration 异常,

下面这张图描述了生成器函数定义体的执行过程。

569b1454ff634c0fb60bea7de7d3ae9.jpg

在for循环中,会通过 iter(gen_AB()) 来获取生成器对象,然后每次迭代时调用 next(g), for 机制会捕获 StopIteration 异常,因此循环终止时没有博爱错。

生成器表达式

生成器表达式像列表推导式的写法,不过使用 小括号括起来,生成器表达式返回的是一个 生成器对象,需要通过迭代来取出值。