迭代器和可迭代对象
from collections import Iterable, Iterator class ClassIterator: """迭代器必须实现__iter__和__next__方法,故迭代器一定是可迭代对象""" def __init__(self, obj): self.obj = obj self.position = 0 def __iter__(self): pass def __next__(self): if self.position < len(self.obj.names): next_value = self.obj.names[self.position] self.position += 1 return next_value else: raise StopIteration class ClassMate: """只要实现了__iter__方法就是可迭代对象,可迭代对象返回一个迭代器""" def __init__(self): self.names = ["zhang san", "li si", "wang wu"] def __iter__(self): return ClassIterator(self) classmate = ClassMate() class_iterator = ClassIterator(classmate) print(isinstance(classmate, Iterable)) # 返回True,因为实现了__iter__方法,所以是可迭代对象 print(isinstance(classmate, Iterator)) # 返回false,因为没有实现__next__方法,所以不是迭代器 print(isinstance(class_iterator, Iterable)) # 返回True,实现了__iter__ print(isinstance(class_iterator, Iterator)) # 返回True,实现了__iter__和__next__ """for语句首先用iter(classmate)获取一个迭代器,然后用next(迭代器)逐个获取元素,直到捕捉到StopIteration""" for i in classmate: print(i)
总结:
1、对象A重载了__iter__方法(甚至方法体是pass),那么A就是可迭代对象,即isinstance(A,Iterable)返回True
2、对象A重载了__iter__方法和__next__方法,那么A就是一个迭代器,即isinstance(A,Iterator)返回True
3、iter(A)触发A的__iter__方法,__iter__返回一个迭代器
4、next(迭代器)触发迭代器的__next__方法
5、for i in A的执行流程为:先调用iter(A)获取一个迭代器B,然后执行next(B),直到B抛出StopIteration异常
事实上,迭代器和可迭代对象可以合二为一,当一个对象实现了__iter__和__next__,那么它既是可迭代对象,又是迭代器,__iter__可以返回它自己,而不需要额外去写一个迭代器,比如上面的示例可以简化为:
class ClassMate: def __init__(self): self.names = ["zhang san", "li si", "wang wu"] self.position = 0 def __iter__(self): # 本身是一个迭代器 return self def __next__(self): if self.position < len(self.names): next_value = self.names[self.position] self.position += 1 return next_value else: raise StopIteration classmate = ClassMate() for i in classmate: print(i)