1.可迭代对象Iterable和迭代器Iterator的区别
Iterable中实现__iter__方法,__iter__方法会返回一个Iterator。注意,这里返回的是一个迭代器。自定义可迭代类的时候,要返回一个迭代器,不能return self,自己不是一个迭代器。
迭代器继承自Iterable,实现__next__,可以重写__iter__。自定义一个迭代器,__iter__中可以return self,自己实现了__next__,就是个迭代器。
2.iter()方法做了什么?
l = [1,2,3,4]
a=iter(l)#iter()调用了列表的__iter__,返回l迭代器对象,使a能使用__next__
3.for循环原理
for 循环在工作时,首先会调用可迭代对象内置的iter方法拿到一个迭代器对象,然后再调用该迭代器对象的next方法将取到的值赋给item,执行循环体完成一次循环,周而复始,直到捕捉StopIteration异常,结束迭代
4.getitem 也是模拟的返回一个迭代器
for循环中,如果对象没有__iter__,但是实现了__getitem__,会改用下标迭代的方式
classPerson:def __init__(self,persion_list):
self.persion_list=persion_listdef __getitem__(self, item):returnself.persion_list[item]
body=Person(["Xiuwu","Adny","Maggie"])for i inbody:print (i)
当for发现没有__iter__但是有__getitem__的时候,会从0开始依次读取相应的下标,直到发生IndexError为止,这是一种旧的迭代协议。
5.有些可迭代对象中__iter__,返回的是return iter(some_cls),这里 __iter_ 方法 是需要通过 iter() 显示的转成 iterator.
class test: #test 类支持迭代协议,因为它定义有__iter__()函数
def __iter__(self):
self.result=[1,2,3]return iter(self.result) #返回的是可迭代对象
a=test()print(type(a))
b= iter(a) #b 拥有了__next__方法(next(b)),调用a的__iter__方法
print(next(b))
6.自定义迭代器
classPerson:def __init__(self):
self.n=0def __iter__(self):return self
def __next__(self):
whileTrue:if self.n > 6:raiseStopIteration
self.n+= 1
returnself.n
a=Person()
b=iter(a)#print(next(b))#print(next(b))#print(next(b))#print(next(b))#print(next(b))#print(next(b))#print(next(b))#print(next(b))
for i initer(a):print("sd")print(i)
from collections importIterable, IteratorclassPerson:def __init__(self, persion_list):
self.persion_list=persion_listdef __iter__(self):return Myiterator(self.persion_list) #调用我们重写的迭代器方法
#def __iter__(self):
#return 1
#def __getitem__(self, item): #把这个方法用我们自己写的迭代器方法替代.
#return self.persion_list[item]
class Myiterator(Iterator): #继承Iterator 就不需要写__iter__,直接调用父类的.
def __init__(self,persion_list):
self.persion_list=persion_list
self.index=0 #由于iterator 是没有index 的,这个要我们手动添加
def __next__(self): #这个就是迭代器的取值逻辑
while True: #当为false 的时候结束循环
try:
word= self.persion_list[self.index] #取值动作
except IndexError: #index 当变得超出persion_list 会报错的 ,先抓住这个异常
raise StopIteration #迭代到没有值要用这异常,咱们把异常做个转化
self.index = self.index + 1 #递增我们的index
return word #返回取到的值
body= Person(["Xiuwu", "Adny", "Maggie"])
a=iter(body) #调用我们自定义的迭代器方法
print(a) #<__main__.myiterator object at>
#从打印结果看说明我们自定义的迭代器方法生效了,已经返回一个迭代器
print(next(a)) #Xiuwu
#从打印结果我们判断出 __next__生效,如果想循环输出,自己试试for 循环.