转载请注明出处:https://blog.csdn.net/jpch89/article/details/84645251
namedtuple
大多数翻译作具名元组或命名元组,个人喜欢前者的译法。
具名元组可以理解为元组的增强版本,它适用于任何普通元组的应用范围。
具名元组为元组中的每个元素都赋予了含义,从而增强代码可读性,能够让程序员写出自文档化 self-documenting
的代码。
namedtuple()
工厂函数返回一个具名元组类,该函数位于 collections
模块下,具体定义形式如下:
namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)
namedtuple
返回一个元组的子类(即具名元组类),类名为 typename
。
通过具名元组类创建出来的具名元组对象,其内部元素支持属性查找(点号语法)、索引操作(方括号语法),并且是可迭代的。
具名元组对象还有自动生成的文档字符串,和一个 __repr__()
方法,把具名元组对象展示为 name=value
的格式。
下面是一小段示例代码:
from collections import namedtuple
Student = namedtuple('Student', 'name, gender')
s = Student('小花', '女')
# 属性访问
print(s.name)
print(s.gender)
"""
小花
女
"""
# 索引取值
print(s[0])
print(s[1])
"""
小花
女
"""
# 可迭代
for i in s:
print(i)
"""
小花
女
"""
# docstring
print(s.__doc__)
"""
Student(name, gender)
"""
# repr
print(repr(s))
"""
Student(name='小花', gender='女')
"""
field_names
是具名元组的字段名。
它可以通过两种形式指定:
字符串组成的序列
比如 ['x', 'y']
、('x', 'y')
。
一个长字符串,各个字段名之间用空格或逗号分隔
比如 'x y'
或者 'x, y'
字段名必须符合以下规则:
rename
默认为 False
,它是只能以关键字形式指定的参数,或者叫做强制关键字参数 keyword-only argument
。
如果 rename=True
,那么无效的字段名会被替换为 '_索引值'
。
比如 ['abc', 'def', 'ghi', 'abc']
会被转换成 ['abc', '_1', 'ghi', '_3']
。其中与关键字重名的 'def'
和重复的 'abc'
都被替换成了 '_索引值'
。
defaults
参数默认为 None
,是强制关键字参数。
它可以被设置为可迭代对象。
由于默认值参数必须在非默认值参数之后,所以 defaults
参数会被设置给最右边的字段名。
比如字段名为 'x, y, z'
,defaults
参数为 (1, 2)
时,y
默认为 1
,z
默认为 2
,x
则没有默认值。
如果定义了 __module__
的值,那么具名元组类的 __module__
属性就会被设置为该值。
补充
__module__
属性记录类定义的位置,如果定义的位置正好是主程序,那么该值为 '__main__'
,否则是类所属模块的名字。
具名元组对象是轻量级的,它们消耗的内存与普通元组一样,因为它们不会对每个实例都维护一个属性字典。
3.1
:增加了 rename
参数
3.6
:verbose
和 rename
参数变成强制关键字参数
3.6
:增加了 module
参数
3.7
:去除了 verbose
参数和 _source
属性
3.7
:加入了 defaults
参数和 _field_defaults
属性
from collections import namedtuple
# 简单示例
Point = namedtuple('Point', ['x', 'y'])
# 通过位置参数或者关键字参数实例化
p = Point(11, y=22)
# 索引取值
print(p[0] + p[1])
"""
33
"""
# 像普通元组一样解包
x, y = p
print(x, y)
"""
11 22
"""
# 通过名字访问字段
print(p.x + p.y)
"""
33
"""
# __repr__ 展现为 name=value
print(repr(p))
"""
Point(x=11, y=22)
"""
除了从元组继承来的方法和属性,具名元组自己还有三个方法和两个属性。
为了避免与字段名重名,这些方法和属性都以一个下划线开头,这也是为什么字段名不能以下划线开头的原因。
classmethod somenamedtuple._make(iterable)
t = [11, 22]
print(Point._make(t))
"""
Point(x=11, y=22)
"""
somenamedtuple._asdict()
返回一个 OrderedDict
有序字典对象,把字段名映射到相应的值。
p = Point(11, 22)
print(p._asdict())
"""
OrderedDict([('x', 11), ('y', 22)])
"""
3.1
版本开始返回OrderedDict
对象而不是普通字典对象。
somenamedtuple._replace(**kwargs)
_replace
接收关键字参数,给指定的字段重新赋值p = Point(11, 22)
# _replace 不改变原具名元组!
new_p = p._replace(x=33)
print(p)
print(new_p)
"""
Point(x=11, y=22)
Point(x=33, y=22)
"""
somenamedtuple._fields
该属性是由字段名组成的元组。
在内省 introspection
时和从现有的字段名创建新的具名元组类型时很好用。
# 查看具名元组的字段
print(p._fields)
"""
('x', 'y')
"""
Color = namedtuple('Color', 'red green blue')
Pixel = namedtuple('Pixel', Point._fields + Color._fields)
p = Pixel(11, 22, 128, 255, 0)
print(p)
"""
Pixel(x=11, y=22, red=128, green=255, blue=0)
"""
somenamedtuple._fields_defaults
返回一个字典,是字段名和默认值的映射。
Account = namedtuple('Account', ['type', 'balance'], defaults=[0])
print(Account._fields_defaults)
"""
{'balance': 0}
"""
print(Account('premium'))
"""
Account(type='premium', balance=0)
"""
getattr
获取属性# 使用 getattr 获取属性
print(getattr(p, 'x'))
"""
11
"""
# 解包字典作为参数生成具名元组
# 相当于以关键字形式指定的参数
d = {'x': 11, 'y': 22}
p = Point(**d)
print(p)
"""
Point(x=11, y=22)
"""
其它用法比如子类化具名元组另行记述。
完成于 2018.11.30