Python可迭代对象(Iterable)、迭代器(Iterator)和生成器(generator)是三个不同的概念。
可迭代对象:类中含有__iter__方法,且该方法不同于迭代器中的方法,它不能返回自身self,必须返回一个迭代器。
迭代器:类中含有__iter__以及__next__方法,且这两个方法共同组成迭代器协议。内置iter()函数可以生成一个迭代器。
生成器:将一个函数变成生成器,只需在函数中加入 yield 关键字,或者用(),例如g = (i for i in range(5))是一个生成器。
for循环实质上执行两个过程,__iter__调用,__next__获取。因此凡是for循环可作用的对象,一定是迭代器。
for循环之所以能够作用于list、dict等容器,是因为其__iter__方法返回的是一个迭代器,所以本质上还是作用于迭代器。
迭代器一定是可迭代对象,可迭代对象不一定是迭代器(但其__iter__方法一定返回一个迭代器)。之所以要这样设计,是考虑到将迭代器作为一个无限大的数据流,这是容器无法做到的。
生成器可以视为一个特殊类型的迭代器,拥有迭代器的所有属性和方法,通常在函数中加入yield产生。使用时,不一次性全部计算出结果,而时存储函数的代码及状态,等待下一次计算。
测试代码如下:
from collections import Iterator, Iterable
class test:
def __init__(self, data):
self.data = data
def __iter__(self):
# return self
return iter(range(5))
# def __next__(self):
# if self.data > 5:
# raise StopIteration
# else:
# self.data += 1
# return self.data
def gen(self, num):
i = 0
while i < num:
yield self.data
i += 1
t = test(1)
# for i in t.gen(2):
# print(i)
# for _ in range(2):
# print(next(t))
for i in t:
print(i)
print(type(t.gen(2)))
print(isinstance(t, Iterator))
print(isinstance(t, Iterable))