一,迭代器协议和for循环工作机制
(一),迭代器协议
1,迭代器协议:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个stopiteration异常,以终止迭代(只能往后走,不能往前退)
2,可迭代对象:实现了迭代器协议的对象(如何实现,对象内嵌一个__iter__()方法)
3,协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象
(二),for循环工作机制
for循环的本质:循环所有对象,全都是使用迭代器协议
正本清源:(字符串,列表,元组,字典,集合,文件对象)这些都不是可迭代对象,只不过在for循环时,调用了他们内部的__iter__方法,把他们变成了可迭代对象。然后for循环调用可迭代对象的__next__方法去取值,而且for循环会捕捉Stopiteration异常,终止迭代。
例1,__next__()模拟for循环
l = [1,2,3] for i in l: #for循环遵循迭代器协议,先调用l.__iter__()将其转换成一个迭代器,然后使用__next方法得到每一个值 print(i) #for循环模拟 x = 'hello' iter_test = x.__iter__() print(iter_test.__next__()) print(iter_test.__next__()) print(iter_test.__next__()) print(iter_test.__next__()) print(iter_test.__next__()) '''输出: h e l l o '''
例2,取列表的两种方法
l = [1,2,3] #第一种:索引 print(l[0]) #输出:l #索引遍历 index = 0 while index < len(l): print(l[index]) index += 1 '''输出: 1 2 3 ''' #第二种:__next__()方法 iter_l = l.__iter__() print(iter_l.__next__()) #输出:l
(三)for循环存在的作用
序列类型:字符串,列表,元组都有下标,可以使用索引访问,但是非序列类型:字典,集合,文件就不行。
for循环基于迭代器协议提供了一个统一的可以遍历所有对象的方法。
#集合只能使用for循环 s = {'a','b','c'} for i in s: print(i) '''输出: a c b ''' #for循环字典名时,取到的值是字典的key dic = {'aa':1,'bb':2} iter_d= dic.__iter__() print(iter_d.__next__()) #输出:bb #使用for循环文件句柄f的好处是:迭代器只在用的时候返回一个值,而不像readlines把所有内容都加在到内存里 f = open('text.txt','r+') iter_f = f.__iter__() print(iter_f.__next__(),end='') print(iter_f.__next__(),end='') #输出:1111 #输出:2 #使用while语句模拟for循环 l=[1,2,3,4,5] diedai_l=l.__iter__() while True: try: print(diedai_l.__next__()) except StopIteration: print('迭代完毕了,循环终止了') break '''输出: 1 2 3 4 5 迭代完毕了,循环终止了 ''' #内置方法next函数,就是在调用iter_l.__next__() l = ['die','erzi','sunzi','chongsunzi'] iter_l = l.__iter__() print(next(iter_l)) #输出:die #迭代器就是可迭代对象,遵循迭代器协议就是可迭代对象 #怎样把一个数据结构变成可迭代对象,就是调用__iter__()方法 #如果数据结构没有__iter__()方法,就不是可迭代对象