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

Python Cookbook-4.18 搜集命名的子项

任务

你想搜集一系列的子项,并命名这些子项,而且你认为用字典来实现有点不便。

解决方案

任意一个类的实例都继承了一个被封装到内部的字典,它用这个字典来记录自己的状态。我们可以很容易地利用这个被封装的字典达到目的,只需要写一个内容几乎为空的类:

class Bunch(object):
	def __init__(self,**kwds):
		self.__dict__.update(kwds)

现在,为了将变量组织起来,创建一个 Bunch 实例:

point = Bunch(datum = y,squared = y*y,coord = x)

现在就可以访问并重新绑定那些刚被创建的命名属性了,也可以进行添加、移除某些属性之类操作。比如:

if point.squared > threshold:
	point.isok = True

讨论

我们常常需要搜集一些元素,然后给它们命名。这个需求用字典来实现完全没有问题但是利用一个几乎什么都不做的小类明显更加方便美观。

如同解决方案的代码所示,创建一个小小的类,提供参数访问的语法,我们几乎不用写什么东西。字典也适合用来搜集一些子项,每个子项都有自己的名字(根据环境,字典中的子项的键可以被认为是该子项的名字),但如果所有的名字都是标识符,而且被当做变量使用,字典并不是最好的方案。在类Bunch的__init__ 方法中,通过**kwds语法,可以接受任意的命名参数,并且用kwds参数来更新实例的空字典,这样,每个命名的参数都成为实例的一个属性。

与访问属性的语法相比,字典索引语法不是那么简洁和易读。比如,如果point是个字典,解决方案中的最后的那个代码片段就应该是这样:

if point['squared'] > threshold:
	point['isok'] = True

此外,还有另一个备选的实现方案,看上去也很吸引人:

class EvenSimplerBunch(obiect):
	def __init__(self,**kwds):
		  self.__dict__ = kwds

将实例的字典重新绑定可能会让人感到不安,但比起调用字典的 update 方法,它不会造成什么不好的后果。所以,你可能会喜欢这个备选的Bunch 实现在速度上的优势。不过,我从来没有在任何 Python 文档中看到对下面用法的担保:

d = {'foo':'bar'}
x = EvenSimplerBunch(**d)

最好使x.__dict__成为字典d的一个独立的拷贝,而不是共享一个引用。现在这个方法的确有效,在各个版本中都能工作,但除非语法文档规定了其语义,否则我们不能确信这种做法会永远有效。所以,如果选择了EvenSimplerBunch的实现,你可能会选择赋值一个拷贝(dict(kwds)或者 kwds.copy()),而不是kwds 本身。而且,如果这样做,那一点速度优势也就消失了。总之,最好还是将原先的Bunch的实现方法作为首选。

另一个富诱惑的做法是直接让 Bunch 类继承 dict,并将属性访问的特殊方法设为该子项本身的属性方法,像下面这样:

class DictBunch(dict):
	__getattr__ = dict.__getitem__
	__setattr__ = dict.__setitem__
	__delattr__ = dict.__delitem__

这个方法的一个问题是,根据定义,DictBunch的一个实例x会拥有很多它实际上没有的属性,因为它获得了 dict所有的属性(实际上是方法,但在这个环境中其实没什么区别)。所以,你通过 hasattr(x,someattr)来检查属性没有意义,但可以对先前实现的Bunch 和EvenSimplerBunch 这么做,而且,你还得事先排除 someattr 的值是一些通用语如“keys”、“pop”和“get”等的可能性。

Pyihon 的关于属性和子项的区别是这门语言清晰和简洁的源泉。不幸的是,很多 Python新手错误地以为将属性和子项混为一谈并没有什么问题,这大概是因为先前的JavaScript 和其他语言的经验,在JavaScript 中,属性和条目通常是可以混为一谈的。不过新手应该把概念厘清,不要继续稀里糊涂。

相关文章:

  • SAPIEN 仿真环境下的 pose
  • 告别失联!北斗三号多模对讲机TD70破除无网通信难题
  • go中锁的入门到进阶使用
  • 【算法day27】有效的数独——请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
  • 电子电气架构 --- 自动驾驶汽车整体架构
  • Python入门(3):语句
  • 各类神经网络学习:(七)GRU 门控循环单元(上集),详细结构说明
  • Hadoop集群常用命令
  • Kotlin 接口详解
  • 阿里云服务器安装docker以及mysql数据库
  • 集和诚携手Intel重磅发布BRAV-7820边缘计算新品,为车路云一体化场景提供强大算力支撑
  • 鸿蒙如何通过日程管理提高直播上线率
  • 【NLP】16. NLP推理方法重点回顾 -- 52道多选题
  • C#:尝试解析方法TryParse
  • JSON.toJSONString(xxx) @JsonFormat失效
  • 米勒电容-Mos管驱动台阶
  • 系统与网络安全------Windows系统安全(3)
  • 密码学基础——密码学相关概念
  • 0基础入门scrapy 框架,获取豆瓣top250存入mysql
  • nginx作为下载服务器的设定和优化
  • 那个网站教宝妈做辅食/郑州网络推广报价
  • 长春模板建站公司/成都网络营销公司
  • 阿里云绑定wordpress/临沂seo建站
  • 2017网站发展趋势/营销软文代写
  • 十大奢侈品牌logo图片/深度优化
  • 硅谷电视剧他们做的是网站还是软件/现在有什么技能培训班