Python可迭代对象(Iterable)、迭代器(Iterator)和生成器(generator)是三个不同的概念。
可迭代对象:实例化的类中含有__iter__函数
迭代器:实例化的类中含有__iter__以及__next__
生成器:将一个函数变成生成器,只需在函数中加入 yield 关键字
for循环实质上执行两个过程,__iter__调用,__next__获取。
这里注意一点:如果一个类含有__iter__, 那么for循环一定可以作用于该类的对象,但如果iter返回自身self,那么类中必须要声明一个__next__函数(这时该对象同时是一个迭代器)。否则报错(TypeError: iter() returned non-iterator of type ‘test’)。反之若iter返回另一个迭代器,没有next也是可行的,此时该对象仅是一个可迭代对象, 不是迭代器。
for 循环可以作用于任何可迭代对象。
迭代器一定是可迭代对象,可迭代对象不一定是迭代器(不能调用next情况下不是迭代器)。比如list,dict等容器(container)是可迭代对象,但不是迭代器(可用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))