可迭代对象,迭代器,生成器

序列可以迭代的原因:iter函数

解释器需要迭代对象 x 时,会自动调用 iter(x)。

内置的 iter 函数有以下作用。

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

(2) 如果没有实现 __iter__ 方法,但是实现了 __getitem__ 方法, Python 会创建一个迭代器,尝试按顺序(从索引 0 开始)获取元素。

(3) 如果尝试失败,Python 抛出 TypeError 异常,通常会提示“C object is not iterable”(C 对象不可迭代),

其中 C 是目标对象所属的类。


任何 Python 序列都可迭代的原因是,它们都实现了 __getitem__ 方 法。其实,标准的序列也都实现了 __iter__ 方法,

因此你也应该这么 做。之所以对 __getitem__ 方法做特殊处理,是为了向后兼容,而未 来可能不会再这么做

鸭子类型(duck typing)的极端形式:不仅要实现 特殊的 __iter__ 方法,

还要实现 __getitem__ 方法,而且 __getitem__ 方法的参数是从 0 开始的整数(int),这样才认为对象 是可迭代的。

在白鹅类型(goose-typing)理论中,可迭代对象的定义简单一些,不过 没那么灵活:

如果实现了 __iter__ 方法,那么就认为对象是可迭代 的。

此时,不需要创建子类,也不用注册,因为 abc.Iterable 类实现 了 __subclasshook__ 方法,



我们要明确可迭代的对象和迭代器之间的关系:Python 从可迭代的对象 中获取迭代器。

标准的迭代器接口有两个方法:

__next__

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

__iter__

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

因此, 迭代器的定义

迭代器是这样的对象:实现了无参数的 __next__ 方法,返回序列 中的下一个元素;

如果没有元素了,那么抛出 StopIteration 异常。

Python 中的迭代器还实现了 __iter__ 方法,因此迭代器也可以迭代。



只要 Python 函数中包含关键字 yield,该函数就是生成器函数。

生成器表达式可以理解为列表推导的惰性版本:不会迫切地构建列表, 而是返回一个生成器,按需惰性生成元素。

也就是说,如果列表推导是 制造列表的工厂,

那么生成器表达式就是制造生成器的工厂。

从下图可以看出:

[ ] 是 列表推导式

()  则就变成了生成器,即 generator

你可能感兴趣的:(可迭代对象,迭代器,生成器)