执行过程:
for temp in xxx_obj: pass 1.先判断xxx_obj是否可以迭代的对象; 2.如果xxx_obj是可迭代的,自动调用iter函数,iter函数自动调用xxx_obj对象的__iter__方法; 3.如果xxx_obj对象的__iter__方法的返回值是一个迭代器,之后for通过自动调用next函数来间接调用迭代器里的__next__函数来取出数据.模拟的代码如下:用两个类模拟,一个是创建可迭代对象的类,一个是创建迭代器的类。
from collections.abc import Iterable, Iterator # 迭代器类 class ClassIterator(object): def __init__(self): pass def __iter__(self): pass def __next__(self): """同时有__iter__和__next__的类创建的对象是一个迭代器""" return "nice" # 可迭代对象类 class Classmate(object): def __init__(self): self.names = list() def add(self, name): self.names.append(name) def __iter__(self): """只要添加__iter__方法,该类创建的对象就是可以迭代的对象""" return ClassIterator() # 返回一个迭代器 def main(): classmate = Classmate() # 模拟for执行 # 1. 判断是否是可迭代的对象 print("classmate是否是可以迭代的对象:", isinstance(classmate, Iterable)) # 2.iter调用可迭代对象的__iter__,并返回一个迭代器 if isinstance(classmate, Iterable): # iter会调用实参classmate的__iter__,返回一个迭代器 classmate_iterator = iter(classmate) print("classmate_iterator是否是迭代器:", isinstance(classmate_iterator, Iterator)) # 3.next调用迭代器的__next__,返回数据 if isinstance(classmate_iterator, Iterator): # next会调用实参classmate_iterator的__next__ print(next(classmate_iterator)) if __name__ == "__main__": main()代码执行结果:
classmate是否是可以迭代的对象: True classmate_iterator是否是迭代器: True nice注:如果上面的代码不好理解,可以先看下面的代码
from collections.abc import Iterable, Iterator # 迭代器类 class ClassIterator(object): def __init__(self, another_obj): # 将要遍历的对象赋值给迭代器的self.obj self.obj = another_obj # 存储待遍历的对象 self.current_num = 0 # 下标,记录当前遍历到哪个元素 def __iter__(self): pass def __next__(self): """同时有__iter__和__next__的类创建的对象是一个迭代器""" if self.current_num < len(self.obj.names): ret = self.obj.names[self.current_num] self.current_num += 1 return ret else: raise StopIteration # 抛出异常,遍历结束 # 可迭代对象类 class Classmate(object): def __init__(self): self.names = list() def add(self, name): self.names.append(name) def __iter__(self): """只要添加__iter__方法,该类创建的对象就是可以迭代的对象""" return ClassIterator(self) # 创建返回一个迭代器,要遍历self,所以要传递self def main(): classmate = Classmate() classmate.add(10) classmate.add(20) classmate.add(30) for temp in classmate: print(temp) if __name__ == "__main__": main()迭代器作用:使用迭代器,可以不用预先知道要分配多大的空间,当数据规模比较大时,如果使用列表、元组等来存储数据,需要开辟很大的内存空间。而使用迭代器可以不用分配这么大的空间,迭代器是在不断迭代遍历的时候生成数据。迭代器不存储要遍历的数据,而是存储产生该数据的方式。一般用于遍历有规律的数据。 例子:遍历斐波那契数列
class Fibonacci(object): def __init__(self, all_num): self.all_num = all_num # 要创建多少个数 self.current_num = 0 # 当前已经创建的个数 self.a = 0 self.b = 1 def __iter__(self): return self def __next__(self): """只要不抛出异常,for就会一直调用__next__""" if self.current_num < self.all_num: ret = self.a self.a, self.b = self.b, self.a+self.b self.current_num += 1 return ret else: raise StopIteration if __name__ == "__main__": all_cnt = 8 fib = Fibonacci(all_cnt) cnt = 1 for num in fib: # 将__next__返回的结果赋值给num if cnt < all_cnt: print(num, end=",") else: print(num) cnt += 1结果:
0,1,1,2,3,5,8,13