当前位置: 首页 > backend >正文

Python Cookbook-6.7 有命名子项的元组

任务

Python 元组可以很方便地被用来将信息分组,但是访问每个子项都需要使用数字索引,所以这种用法有点不便。你希望能够创建一种可以通过名字属性访问的元组。

解决方案

工厂函数是生成符合要求的元组的子类的最简单方法:

#若在2.4中可使用operator.itemgetter,若在2.3中则需要实现itemgetter
try:from operator import itemgetter
except ImportError:def itemgetter(i):def getter(self):return self[i]return getterdef superTuple(typename,*attribute_names):"创建并返回拥有名字属性的元组子类"#给子类适合的__new__和__repr__特殊方法nargs = len(attribute_names)class supertup(tuple):#我们不需要每个实例提供一个字典,节省内存__slots__ = ()def __new__(cls,*args):if len(args) != narqs:raise TypeError,'%s takes exactly %d arquments(%d given)'%(typename,nargs,len(args))return tuple.__new__(cls,args)def __repr__(self):return '%s(%s)'%(typename,','.join(map(repr,self)))#给我们的元组子类添加一些键for index,attr_name in enumerate(attribute_names):setattr(supertup,attr_name,property(itemgetter(index)))supertup.__name__ = typenamereturn supertup

讨论

你常常需要用元组传递数据,就像C语言中的结构,或者其他语言中的简单记录一样。但你总是需要记住每个数字索引对应到哪个城并需要用数字索引来访问数据,这种用法令人心烦。一些 Python 标准库模块,比如 time 和 os,在旧版 Python 中总是返回元组,让这种烦恼更是雪上加霜。事实上,如果有一个类似于元组的类型,可以允许你通过名字访问值,就像通过属性名访问一样,同时也提供了数字索引的访问方式,那一定会是个很受欢迎的方案。本节展示了如何编程来实现这样的效果,本质上我们只需要自动地创建一个元组的定制子类。

要创建一个新的定制类型有很多方法,定制元类对于此类任务通常是最好的方式。但在本节中,一个简单的工厂函数足矣,而且你也应该避免使用超出需求的技术。下面展示怎样在代码中使用工厂函数superTuple,此处假设你已经将解决方案中的代码存为一个名为 supertuple.py的模块,并将它放入了你的Python的sys.path中:

>>> import supertuple
>>> Point = supertuple.superTuple('Point','x','y')
>>> Point
<class 'supertuple.Point'>
>>>p = Point(1,2,3)#故意给错误的数字
Traceback (most recent call last):File "",line 1 in?File "C:\Python24\Lib\site-packages\superTuple.py",line 16, in __new__ raise TypeError,'%s takes exactly %d arguments (%d given)' %
TypeError:Point takes exactly 2 arguments(3 given)
>>> p = Point(1,2)#这次给正确的数字
>>> p
Point(1,2)
>>> print p.x,p.y
1 2

函数 superTuple 的实现相当直接易懂。为了创建新的子类,superTuple 使用了一个 class声明,在声明的主体部分,它定义了三个特殊方法:一个“空”的__slots__(为了节省内存,我们的 supertuple 类并不需要为每个实例提供一个字典);一个__new__方法,这是为了在托管给 tuple.__new__之前先检查参数的个数;以及一个__repr__方法。当一个新的类对象被创建之后,我们为每个我们需要的命名属性设置了一个 property。每个这样的 property 都只是一个“getter”,这是因为我们的 supertuples 就像元组一样,是不可改变的——没有对值域进行设置的方法。最后,我们设置新类的名字并返回类对象。

通过简单地调用标准库模块 operator 的内建的 itemgetter 就可以创建这些 getter 方法。不过由于 operator.itemgetter 在 Python 2.4 中才被引入,在模块的开头我们需要确定用什么方式才能获得可用的itemgetter,即使是在Python2.3中,我们也可以提供自己的实现。

http://www.xdnf.cn/news/1054.html

相关文章:

  • RAG vs 微调:大模型定制化技术选型全解析
  • 10、Context:跨维度传音术——React 19 状态共享
  • 【Java核心技术卷Ⅰ-第11版学习-第3章-Java的基本程序设计结构】
  • 每日一题(9) 垃圾箱分布
  • 基于SpinrgBoot+Vue的智慧农业管理平台-031
  • 远程医疗系统如何有效防护CC攻击
  • 智慧教室电子班牌-智能管理系统源码,‌后端‌基于Spring Boot框架,前端‌使用Vue.js框架进行组件化开发
  • 在python中装饰器的使用
  • File工具总结
  • 悟空黑桃A邀请码(31187835)
  • VSCode远程图形化GDB
  • 算法 | 鲸鱼优化算法(WOA)与强化学习的结合研究
  • Dify-web开发思路
  • Pikachu靶场-SQL注入
  • STM32——相关软件安装
  • 【Linux】:HTTPS协议
  • 相机标定(输出相机内参和畸变参数)
  • ASP.NET 中防止用户多次登录的方法
  • wkhtmltopdf - HTML转PDF/图像命令行工具
  • python@staticmethod 是什么含义?
  • Coze平台​ 创建AI智能体的详细步骤指南
  • 多源异构网络安全数据(CAPEC、CPE、CVE、CVSS、CWE、ATTCK、D3FEND)的详细解析,包括其作用、数据内容及相互联系
  • 跨越1640年的诗路对话:谢灵运与瓯江山水的古今交响
  • EasyCVR视频汇聚平台安防监控问题排查:GB28181协议摄像头不在线的排查步骤
  • 基于Spring Boot实现文件秒传的完整方案
  • 5565反射内存网络产品
  • 【数据结构_11】二叉树(5)
  • JVM面试题学习
  • 算法复杂度
  • Oracle RMAN同步数据库Active database duplicate