迭代器
This document proposes an iteration interface that objects can provide to control the behaviour of ‘for’ loops. Looping is customized by providing a method that produces an iterator object.
–pep234
迭代器不是python与生俱来的概念,而是在pep234中提出来的, 主要用于自定义for语句的逻辑。在迭代器实现之前,python的for语句只能够用在实现了sequence protocol的对象,比如list、string、tuple上, 而pep234之后,for语句的作用对象增加了一个iterators。这样一来只要是实现了iterators 协议的对象都可以用在for语句之中。
什么是迭代
在python中,for语句用于迭代,大致有以下的形式:
1 | for i in iterable: |
一个for的语义是: 接受一个可迭代对象(iterable object),每次从可迭代对象中取出一个元素,赋值给循环变量用于循环体,直至可迭代对象中的元素取完。从这个语义,我们须要解决两个问题:1. 什么是可迭代对象;2. 由谁以及如何从可迭代对象中取出元素。
在python上等价于下面的语句:
1 | iterator = iter(iterable) # 接受一个可迭代对象,获取它的迭代器 |
什么是可迭代对象
An object capable of returning its members one at a time.
——python reference
实际上,一个对象只要定义了__iter__()或者__getitem__()方法,那么这个对象就是可迭代的。暂时只对__iter__进行讨论,一个 可迭代对象为了让for知道如何从自身中取出一个元素,它实现了__iter__方法,返回一个迭代器对象,对,迭代器对象就是一个定义了取出这个操作的对象。
什么是迭代器
An object representing astream of data. Repeated calls to the iterator’s next() method return successive items in the stream.
——python reference
python的reference介绍说迭代器代表的是一个数据流。似乎有点抽象,这样子说吧,在for的语义中,它接受一个可迭代对象,但是for须要知道如何迭代这个对象中的元素,或者说如何从这个对象中取出元素,所以,iter()将会返回可迭代对象的迭代器,相当于可迭代对象在告诉for:”hi,这个家伙(迭代器)知道怎么从我这里取得元素,你只要调用他的next()方法就好,如果我已经没有元素要给你了,他将会抛出一个StopIteration异常”
所以呢,一个迭代器对象须要实现next()方法,这个方法定义了如何从一个迭代器对象中取得元素,在停止时,将会抛出StopIteration异常。另外,为了在能够使用可迭代对象的地方使用迭代器,一个迭代器还会实现__iter__()方法,这个方法返回迭代器自身。
iterator 协议
在pep234中提到,iterator协议主要包括两个方法,主要用于实现上述的迭代器行为:
__iter__():
该方法返回该可迭代对象的迭代器,迭代器知道如何从可迭代对象中获取下一个元素。对于迭代器对象来说,该方法将会返回自身。
next():
该方法实现了该迭代器从可迭代对象中获取下一个元素的方法。
举个例子
1 | class O(object): |