您的位置:首页 > 编程语言 > Python开发

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

2018-11-04 20:56 330 查看

今天准备写一写在学习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]

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: