Python:collections.namedtuple详解
前提
由于tuple
具有局限性:不能为元组内部的数据进行命名,所以往往我们并不知道元组内部每个位置的内容代表什么意思
因此在这里引入了 collections.namedtuple
这个工厂函数,来构造一个带字段名的元组。
🎶注:工厂模式的定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。
- 使用
namedtuple
会创建一个元组的子类(工厂),需用通过实例化(创建工作)才能创建具体的对象
基本概念
命名元组(namedtuple)可以赋予元组每个位置含义。它们可以用于任何普通元组,并添加了通过名字获取值的能力,通过索引值也是可以的。
参数解析
collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)
-
typename
:必填要生成的元组子类的名字,例如
Point
-
field_names
:必填用于定义每个位置的含义
-
可以是一个字符串序列,例如
[x, y]
-
可以是一个纯字符串,用空白或逗号分隔开元素名,比如
'x y'
或者'x, y'
Point = namedtuple('Point', ['x', 'y']) Point = namedtuple('Point', 'x y') Point = namedtuple('Point', 'x, y')
-
-
rename
:选填,默认为False
如果
rename
为真, 无效字段名会自动转换成位置名。例如['abc', 'def', 'ghi', 'abc']
转换成['abc', '_1', 'ghi', '_3']
, 消除关键词def
和重复字段名abc
。Point = namedtuple('Point', ['abc', 'def', 'ghi', 'abc'], rename=True) a = Point(1,2,3,4) print(a) # Point(abc=1, _1=2, ghi=3, _3=4)
-
defaults
:选填,默认为None
可以为
None
或者是一个默认值的 iterable,由于具有默认值的字段必须位于没有默认值的字段之后,因此在defaults
在与field_names
进行匹配的时候,会从右向左匹配。例如field_names
为['x', 'y', 'z']
,defaults
为(1, 2)
,那么x
就必须指定一个参数值 ,y
默认值1
,z
默认值2
。Point = namedtuple('Point', ['x', 'y', 'z'], defaults=(1,2)) a = Point(666) print(a) # Point(x=666, y=1, z=2)
-
module
:选填,默认为None
如果
module
值有定义,命名元组的__module__
属性值就被设置。Point1 = namedtuple('Point', ['x', 'y', 'z'], defaults=(1,2)) Point2 = namedtuple('Point', ['x', 'y', 'z'], module="bingo") a = Point1(666) b = Point2(1,2,3) print(a.__module__) # __main__ print(b.__module__) # bingo
注:命名元组实例没有针对每个实例的字典,因此它们是轻量级的,并且不需要比常规元组更多的内存。
实例
>>> # Basic example
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(11, y=22) # instantiate with positional or keyword arguments
>>> p[0] + p[1] # indexable like the plain tuple (11, 22)
33
>>> x, y = p # unpack like a regular tuple
>>> x, y
(11, 22)
>>> p.x + p.y # fields also accessible by name
33
>>> p # readable __repr__ with a name=value style
Point(x=11, y=22)
属性和方法
除了继承元组的方法,命名元组还支持三个额外的方法和两个属性。为了防止字段名冲突,方法和属性以下划线开始。
方法
_make()
classmethod somenamedtuple._make(iterable)
是一个从存在的序列或迭代实例创建一个新实例的类方法。
Point = namedtuple('Point', ['x', 'y'])
t = [11, 22]
Point._make(t) # Point(x=11, y=22)
_asdict()
somenamedtuple._asdict()
返回一个新的 dict
,它将字段名称映射到它们对应的值
>>> p = Point(x=11, y=22)
>>> p._asdict()
{'x': 11, 'y': 22}
_replace(**kwargs)
somenamedtuple._replace(**kwargs)
返回一个新的命名元组实例,并将指定域替换为新的值
>>> p = Point(x=11, y=22)
>>> p._replace(x=33)
Point(x=33, y=22)
属性
_fields
somenamedtuple._fields
将namedtuple中的键输出成元组的形式,用于自我检查或者从现有的namedtuple中创建新的namedtuple
>>> p._fields # view the field names
('x', 'y')
>>> Color = namedtuple('Color', 'red green blue')
>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)
>>> Pixel(11, 22, 128, 255, 0)
Pixel(x=11, y=22, red=128, green=255, blue=0)
_field_defaults
somenamedtuple._field_defaults
将默认的键值对整理成字典的形式
>>> Account = namedtuple('Account', ['type', 'balance'], defaults=[0])
>>> Account._field_defaults
{'balance': 0}
>>> Account('premium')
Account(type='premium', balance=0)
其他操作
获取键的值
要获取某个键的值,使用 getattr()
函数 :
>>> p = Point(x=11, y=22)
>>> getattr(p, 'x')
11
将字典转换成namedtuple
转换一个字典到命名元组,使用 ** 两星操作符
>>> Point = namedtuple('Point', ['x', 'y'])
>>> d = {'x': 11, 'y': 22}
>>> Point(**d)
Point(x=11, y=22)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步