Python中的可迭代对象、迭代器对象和迭代器协议之间的联系和区别

今天准备写一写在学习python过程中,自己对于迭代器、迭代器协议以及可迭代对象之间的关系及自己的理解。可能有些不对的地方,欢迎大家及时指正。

可迭代对象

可迭代对象泛指一类对象,不是指的每一种对象,确切的说满足以下的条件的对象可以成为可迭代对象:

  • 对象实现了__iter__方法
  • __iter__方法返回了一个迭代器对象

我们比较容易理解的可迭代对象,比如说可以用for语句去遍历,实际for语句的内部实现应该就是首先调用对象的__iter__方法,获取一个迭代器对象,接着不停的调用迭代器对象的__next__方法,循环遍历取值。

迭代器对象(迭代器)

在可迭代对象我们提到了迭代器对象,什么是迭代器对象?同样这里泛指一类满足一些条件的一类对象,就可以称之为迭代器对象。也就是满足迭代器协议的一类对象。

协议: 我个人理解是对一系列条件的描述。

迭代器协议包括这些条件:

  • 对象实现了__next__方法
  • __next__方法返回了某个数值(当然一般情况下,我们需要的是返回这个对象的特定的数字,并且按照一定的顺序进行依次返回)
  • __next__方法需要在值取完的时候,抛出StopIteration的错误信息。

总结:

  1. 可迭代对象是 调用对象的__iter__方法能够返回迭代器对象的一种对象。
  2. 迭代器对象是实现了迭代器协议的对象。

那么有没有一种情况,就是一个对象本身自己就是迭代器对象,同时__iter__方法返回自己,这样自己就满足了可迭代对象,迭代器对象的两重要求。
实际上,大部分内建的容器对象,例如字典、列表等,都是这样实现的,他们对象本身就是迭代器对象。

我们通过一个自己写一个可迭代对象,来让大家更深入的了解。
比如:

    for i in range(1,10,1):
        ...

这个大家应该不陌生,实际上range(1,10,1)生成的就是一个可迭代对象,遍历它会一次获取1 - 9 的自然数,我们就自己实现一个MyRange类,达到同样的效果。

class MyRange:
    def __init__(self,start_index,end_index,step):
        # 这里为了简化,我们就不考虑默认值的情况了,要让用户必须输入起始数值和步长,也不考虑步长为负数的时候反向取值了,默认只能输入正数。
        self.start_index = start_index
        self.end_index = end_index
        self.step = step


    def __iter__(self):
        # 接下来,我们就来实现可迭代对象的一个性质,返回迭代器对象,这里我们返回了一个M\yRangeIteration对象,同时用起始值和步长对,迭代器对象进行初始化,接下来我们会来定义这个迭代器对象.
        return MyRangeIteration(self.start_index,self.end_index,self.step)


class MyRangeIteration:
    def __init__(self,start,end,step):
        self.start = start 
        self.end = end 
        self.step = step

    def __next__(self):
        # 迭代器对象的要求是实现迭代器协议,1.实现了__next__方法,
        if self.start < self.end :
            result = self.start
            # 以step步距调整self.start的值,为下一次的调用做准备。
            self.start += self.step
            # 2. 返回一个值
            return result 
        else:
            # 3. 没有值可以取了,抛出异常StopIteration
            raise StopIteration

if __name__ == '__main__':
    for i in MyRange(1,10,1):
        print(i)

我们得到以下结果:

1
2
3
4
5
6
7
8
9
[Finished in 0.3s]

这样我们通过一个简单的实例,了解了可迭代对象和迭代器对象这几个概念之间的差别和联系。在我学习的时候,反正自己是花了很长一段时间,才算弄清楚。
希望以上的东西,能够帮到初学者,同时也欢迎大家对不足的地方进行指正。

你可能感兴趣的:(python)