关于 Python Iterator 协议的一点思考

转:http://www.jianshu.com/p/dcf83643deeb

Python 中有好几种容器或者序列类型:list tuple dict set str,对于这些类型中的内容,往往需要一种方式去遍历获取它们来进行操作。所以 Python 提供了迭代器的类型来对这些类型的内容进行迭代遍历,迭代类型新增于 Python 2.2。

迭代器类型指的是遵循迭代器协议的类型,对于 Python2.x 版本来说就是实现了 __iter__ 和 next 函数的对象类型。如果一个对象实现了迭代器协议,则可以用 for 语句遍历这个对象的内容。其中 __iter__ 函数返回一个迭代器对象,而 next 函数则需要返回容器的下一个内容,如果没有下一个则抛出 StopIteration 异常,这个异常在 for ... in 语句中将会被捕获然后结束迭代。迭代器协议详细内容可以查看 PEP234 。Python3.x 将 next 函数改成了 __next__ 函数,以和其他内置的函数保持一致的双下划线风格。

以前看迭代器协议的时候,经常可以看到这样一个实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    class Reverse(object):

        def __init__(self, data):
            self.data = data
            self.index = len(data)

        def __iter__(self):
            return self

        def next(self):
            if self.index == 0:
                raise StopIteration
            self.index -= 1
            return self.data[self.index]

最近看到了这么一个写法:

1
2
3
4
5
6
7
8
    class IterObj(object):

        def __init__(self, data):
            self.data = data

        def __iter__(self):
            return iter(self.data)

这个写法没有 next 函数了,初看起来好像没有完全实现迭代器协议的样子,但是仔细考虑下的话,__iter__ 函数内部调用了内置函数 iter ,实际上是返回了一个迭代器对象,而这个迭代器对象当然是实现了迭代器协议的。所以第二种写法也是完全可以的,并且对比第一种写法来说更加简单。

在官方文档 迭代器类型 中可以看到,对于 list dict 等容器对象来说,它们的 __iter__ 函数返回的不是其自身,而是一个迭代器对象: container.__iter__() 。所以当一个容器对象需要提供迭代的功能的时候,不是把这个容器对象变成一个迭代器对象,而是返回一个迭代器对象,将迭代的功能委托给这个迭代器对象。所以上面两种写法的区别在于一个是实现了迭代器对象,一个是实现了可迭代的容器对象。所以第二种写法如果稍稍微修改下:

1
2
3
4
5
6
7
    class IterObj(object):

        def __init__(self, data):
            self.data = data

        def __iter__(self):
            return Reverse(self.data)

这样就利用了之前定义的迭代器对象 Reverse 来给对象 IterObj 提供了反向迭代的功能。可以看到,这样的处理方式将迭代的逻辑和容器对象分离了,更加的灵活,容器对象本身也更加精简。

Python 的迭代器协议统一了 Python 中容器对象进行迭代的方式,另一方面来说,也为用户自定义类型添加迭代的功能添加了方便的实现方式,所以无论是从语言的标准化来说还是从用户使用角度的来说都是非常有用的一个协议。

时间: 2024-08-06 13:39:55

关于 Python Iterator 协议的一点思考的相关文章

对扩展openflow协议的一点思考

软件定义X变得越来越火,正所谓,Software is eating the world. 软件定义网络也是如此.不论是在工业界还是学术界都将是一次伟大的革命,都在紧随着这个行业的方向,找自己的研究点,关注着标准化的进展. 各种Controller,原型系统都相继出现,还有的是是做SDN 的Debug,安全,总之让这个生态系统变得更加健壮.尽管南向接口标准非常多,可是openflow适合我们的学习,社区庞大. 以下记录下自己对这个的一点基本的看法. 1.首先要明白的就是,如同其它通信协议一样,o

基于http协议通信的APP安全策略的一点思考

声明一点,我没做过过任何商业APP,以下想法仅仅是个人业余时间的一点思考,若你是专业人员,不吝赐教. 概述 微信开发过程中,会使用到微信服务器提供的API,这些API都是基于HTTP协议调用的,为什么我们自己的APP服务器不采用这种方式呢? 这种方式最直观的好处就是,API设计得足够好时,服务器只需要开发一次,无论前端是 WEB,APP ,APK...都通过http调用API请求数据并响应. 这种方式类似于传统C/S模型的开发,服务端/客户端定义相同序列的数据结构(称之为通信协议),差别在于现在

关于android SDK安装Failed to fetch URL 一点思考

最近SDK出问题了,然后在google下载了一个android-sdk-windows.rar,然后点击SDK Manager,结果一直不能刷新API Level,然后就开始在网上找了好多资料,解决这个问题,修改 HOSTS,    HTTP  和  HTTPS  都不能解决,这给我带来了很大的困惑!   加载不出来的界面错误为: Fetching http://dl-ssl.google.com/android/repository/addons_list-1.xml Failed to fe

Python Iterator and Generator

Python Iterator and Generator Iterator ? 迭代器(Iterator)和可迭代对象(Iterable)往往是绑定的.可迭代对象就是我们平时经常用的list ,string, tuple这种.事实上迭代器的概念会比可迭代对象宽泛很多,一会举几个例子就能明白. ? 在使用list这种数据类型的时候,我们经常会使用下面这种迭代方式: # eg 1 mylist = [1,2,3,4] for x in mylist: print(x) >>>1 >&

关于后台系统自动生成的一点思考

大量实践发现后台管理程序,其实90%的代码都是相同的,当然是在抛弃复杂逻辑业务的情况下,那么如何能高效的节约这些时间呢,那就是接下来我要说的,对于后台系统自动生成的一些思考. 适用情景: 1.表编号id为自增(基于现在大部分表编号都是自增的情况): 2.没有太复杂业务关联关系,比如表的某一个字段,存储了一个json对象,为了平衡后台用户使用,需要友好的分段展示给用户的定制ui界面:还比如表中存储了外键的多个id,但为了方便用户使用,只能已标签name的方式,给用户展示,等等这些超强业务黏合逻辑的

关于前端的一点思考

关于前端的一点思考 Author:tkorays 最近写前端代码,写着写着就突然开始惆怅.忧伤.愤怒.发狂,我TMD到底在干什么啊! 很多东西写了n遍了,但是还是在不停地写着.自己写过的代码也不想再修改完善.重新利用,只是觉得,可能重新写一遍可能要好点.面对这很多库以及框架,虽然喜爱,但是也是有所顾忌,我只要使用其中的一个功能,根本不需要引入这么大的整个库. 事实上,我们可能在动手写任何代码之前,先要思考下,我们到底要的是什么! 0x00 界面真的需要这么炫酷么 在使用某个界面库之前,我们可能先

关于Emit中动态类型TypeBuilder创建类标记的一点思考

  利用TypeBuilder是可以动态创建一个类型,现在有个需求,动态生成一个dll,创建类型EmployeeEx,需要继承原dll里面的Employee类,并包含Employee类上的所有类标记.   网上有很多例子, //创建TypeBuilder. TypeBuilder myTypeBuilder = myModBuilder.DefineType(typeName, TypeAttributes.Public); myTypeBuilder.SetParent(type);   大概

关于失败的一点思考

睡觉之前突然想到马云说过的一句话:我们要习惯于拒绝,习惯失败,如果我们还没成功,那是因为我们的失败还不够 --------2016.4,11  以此自勉 关于失败的一点思考

有关盒模型的一点思考

有关盒模型的一点思考 盒子模型是css中一个重要的概念,理解了盒子模型才能更好的排版. 其实盒子模型有两种,分别是标准 w3c 盒子模型和 IE 盒子模型. 他们对盒子模型的解释各不相同,先来看看我们熟知的标准盒子模型: 一.w3c盒子模型 看下面的图,根据色块,右外倒内,分别代表margin.border.padding.content(即网页内容部分) 二.IE盒子模型 与w3c盒子模型的组成部分类似,IE盒子模型也包括上图几个部分 但是不同的是,IE盒子模型把border和padding归