具名元组来自 Python 内置库 collections.nametupled 中, 可以用来构建带字段名的元组和一个相应的类collections.namedtuple 是一个工厂函数,它可以用来构建一个带字段名的元组和一个有名字的类——这个带字的类对调试程序有很大帮助
用 namedtuple 构建的类的实例所消耗的内存跟元组是一样的,因为字段名都被存在对应的类里面。这个实例跟普通的对象实例比起来也要小一些,因为 Python 不会用 __dict__ 来存放这些实例的属性。
具名元组顾名思义可以理解为有具体名字的元组,有点类似字典,不过具名元组的值是不能改变的。
已经有了普通元组,为什么还需要具名元组?
因为普通元组,无法为元组内部的数据起名字,经常会疑惑一个元组到底要表达什么意思。而具名元组,则可以通过字段名访问
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(11, y=22) # 用位置参数或关键字实例化
>>> p[0] + p[1] # 和普通元组一样可以使用索引
33
>>> x, y = p
>>> x, y
(11, 22)
>>> p.x + p.y
33
>>> d = p._asdict() # 具名元组转换成字典
>>> d['x']
11
>>> Point(**d) # 字典转换成具名元组
Point(x=11, y=22)
>>> p._replace(x=100) # _replace() is like str.replace() but targets named fields
Point(x=100, y=22)
展示了具名元组来记录一个城市的信息的实例
>>> from collections import namedtuple
# 创建一个具名元组需要两个参数,一个是类名,另一个是类的各个字段的名字
>>> City = namedtuple('City', 'name country population coordinates')
# 存放在对应字段里的数据要以一串参数的形式传入到构造函数中
>>> tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))
>>> tokyo
City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722,139.691667))
>>> tokyo.population # 你可以通过字段名或者位置来获取一个字段的信息
36.933
>>> tokyo.coordinates
(35.689722, 139.691667)
>>> tokyo[1]
'JP'
除了从普通元组那里继承来的属性之外,具名元组还有一些自己专有的属性。下面展示其中几个最常用的方法:_fields
类属性、类方法_make(iterable)
和实例方法_asdict()
。
下面我们一个个讲解
1. 具名元组的_fields
方法:
>>> City = namedtuple('City', 'name country population coordinates')
>>> tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))
>>> tokyo
City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139.691667))
>>> City._fields # _fields相当于打印元组名字
('name', 'country', 'population', 'coordinates')
2. 具名元组的_make(iterable)
方法:
# 接上个实验
>>> LatLong = namedtuple('LatLong', 'lat long')
>>> delhi_data = ('Delhi NCR', 'IN', 21.935, LatLong(28.613889, 77.208889))
>>> City._make(delhi_data)
City(name='Delhi NCR', country='IN', population=21.935, coordinates=LatLong(lat=28.613889, long=77.208889))
3. 具名元组的_asdict()
方法:
# 接上个实验
>>> delhi = City._make(delhi_data)
>>> delhi._asdict() #获得一个有序字典
{'name': 'Delhi NCR', 'country': 'IN', 'population': 21.935, 'coordinates': LatLong(lat=28.613889, long=77.208889)}
# 将上面的字典格式化输出
>>> for key, value in delhi._asdict().items():
print(key + ':', value)
name: Delhi NCR
country: IN
population: 21.935
coordinates: LatLong(lat=28.613889, long=77.208889)
_asdict() 把具名元组以 collections.OrderedDict
的形式返回,我们可以利用它来把元组里的信息友好地呈现出来。
collections.OrderedDict:返回一个有序的字典子类实例,具体可以参考官方文档:collections.OrderedDict