前言

有一个列表

l = ['a','b','c','d','e']
我想取列表中的内容,有几种方式?
# 1.最简单的方法用for循环。    
for i in l:
    print(i,end=" ")
# 2.用列表内置的方法。
while 1:
    if l:
        print(l.pop(),end=" ")

这是用常见的方式取出列表中的数据。

而我们如果遍历数字的话:

for i in 1234:
  print(i)

# 则会报不可迭代的错误。


迭代和可迭代协议

因此,我们知道一种如果能以一种重复执行程序的方式取出数据,那么我们称它为可迭代的。

 

  常见的可迭代数据类型有哪些?

    list、dict、set、tuple、字符串等。说白了就是我们常用循环取数据的那些数据类型。

  那么我们如何判断一个数据类型是否可迭代呢?
from collections import Iterable
print(isinstance(l,Iterable))  # 返回True

可迭代协议

  所谓协议,就是规则嘛。可迭代协议,说白了就说明可迭代是有一套设计好的规则的。如果我们自己写了一个数据类型,希望它是可迭代的,那么我们必须遵守这规则。

   可迭代协议就是内部实现了__iter__方法

   我们可以用反射来判断:

if hasattr(l,"iter"):
    print(True)

  由此以及我们所学所见可知,想要可迭代,内部有一个__iter__方法,那么__iter__方法搞了什么事情?

print(l.__iter__())
<list_iterator object at 0x03BA43B0>

  # 列表_迭代器对象

  

  那么问题来了,什么叫迭代器?可迭代的对象就一定是迭代器吗?

    dir(l.__iter__())是列表迭代器实现的所有方法,那么dir(l)是列表实现的所有方法,此时我们可以用set作差,来看看iter()方法多了什么?

print(set(dir(l.__iter__()))-set(dir(l)))
{'__length_hint__', '__next__', '__setstate__'}  # 看来是这三个方法从中作祟。 
iter_l = l.__iter__()
print(iter_l.__length_hint__()) # 迭代器的长度
print('*',iter_l.__setstate__(3)) # 根据索引值指定从哪里开始迭代
print('**',iter_l.__next__()) # 一个一个的取值
print('***',iter_l.__next__())

  由此可见,