一篇文章弄Python中懂的可迭代对象,迭代器和生成器

  

我们都知道,序列可以迭代。但是,你知道为什么吗?本文来探讨一下迭代背后的原理。

  

序列可以迭代的原因:iter函数。解释器需要迭代对象x时,会自动调用iter (x)内置的iter函数有以下作用:

  

(1)检查对象是否实现了iter方法,如果实现了就调用它,获取一个迭代器。

  

(2)如果没有实现iter方法,但是实现了getitem方法,而且其参数是从零开始的索引,Python会创建一个迭代器,尝试按顺序(从索引0开始)获取元素。

  

(3)如果前面两步都失败,Python抛出TypeError异常,通常会提示“C objectis不是iterable”(C对象不可迭代),其中C是目标对象所属的类。

  

由此我们可以明确知道什么是可迭代的对象:使用iter内置函数可以获取迭代器的对象。即要么对象实现了能返回迭代器的iter方法,要么对象实现了getitem方法,而且其参数是从零开始的索引。

  

下面看一个实现了getitem方法的例子:

  

一篇文章弄Python中懂的可迭代对象,迭代器和生成器”> <br/>
  </p>
  <p>输出结果:</p>
  <p> <img src=

  

我们创建了一个类的烤箱,并且为这个类实现了getitem方法,它的实例化对象o1就是可迭代对象。

  

下面我们看一个实现iter方法的例子,因为用到了迭代器,所以在此我们必须在明确一下迭代器的用法。标准的迭代器接口有两个方法:

  

一篇文章弄Python中懂的可迭代对象,迭代器和生成器

  

返回下一个可用的元素,如果没有元素了,抛出抛出StopIteration异常。

  

一篇文章弄Python中懂的可迭代对象,迭代器和生成器

  

返回自我,以便在应该使用可迭代对象的地方使用迭代器,例如在对循环中。

  

一篇文章弄Python中懂的可迭代对象,迭代器和生成器

  

我们创建了Eg2类,并为它实现了iter方法,此方法返回一个迭代器Eg2Iterator。Eg2Iterator实现了我们之前所说的下一个和iter方法。实例化对象,并循环输出:

  

一篇文章弄Python中懂的可迭代对象,迭代器和生成器

  

可见,和o1群是一样的。

  

我们通过两种方法实现了一个自己的可迭代对象,再此过程中我们要明确可迭代的对象和迭代器之间的关系:

  

Python从可迭代的对象中获取迭代器。

  

iter方法从我们自己创建的迭代器类中获取迭代器,而getitem方法是python内部自动创建迭代器。

  

至此,我们明白了如何正确地实现可迭代对象,并且引出了怎样实现迭代器,但是使用迭代器方法(即上面的例子2)的代码量有点大,下面我们来了解一下如何使用更符合Python习惯的方式实现Eg2类。

  

一篇文章弄Python中懂的可迭代对象,迭代器和生成器

  

哦了!就这么简单优雅!不用再单独定义一个迭代器类!

  

这里我们使用了收益率关键字,只要Python函数的定义体中有产生关键字,该函数就是生成器函数。调用生成器函数时,会返回一个生成器对象。也就是说,生成器函数是生成器工厂。当然,例子3的代码还可以使用收益率从进一步简化:

  

一篇文章弄Python中懂的可迭代对象,迭代器和生成器

  

到这里我们明白了可迭代对象和迭代器,还引申出了生成器,但还有一点没有提,那就是生成器表达式。

  

使用生成器表达式例子4的代码可以修改为:

  

一篇文章弄Python中懂的可迭代对象,迭代器和生成器

  

在python中,所有生成器都是迭代器。

  

<强>最后,总结一下:

  

(1)什么是可迭代对象?可迭代对象要么实现了能返回迭代器的iter方法,要么实现了getitem方法而且其参数是从零开始的索引。

  

一篇文章弄Python中懂的可迭代对象,迭代器和生成器