官方入口:https://docs.python.org/3.7/library/collections.html#collections.namedtuple
collections.
namedtuple
(typename, field_names, *, rename=False, defaults=None, module=None)
用处,代替按位置取元素,使代码更可读。
返回tupple的子类,可用tupple的方法和属性。
field_names 是一个像 [‘x’, ‘y’]
一样的字符串序列。另外 field_names 可以是一个纯字符串,用空白或逗号分隔开元素名,比如 'x y'
或者 'x, y'
。
任何有效的Python 标识符都可以作为字段名,除了下划线开头的那些。有效标识符由字母,数字,下划线组成,但首字母不能是数字或下划线,另外不能是关键词 keyword
比如 class, for, return, global, pass, 或 raise 。
如果 rename 为真, 无效字段名会自动转换成位置名。比如 ['abc', 'def', 'ghi', 'abc']
转换成 ['abc', '_1', 'ghi', '_3']
, 消除关键词 def
和重复字段名 abc
。
defaults 可以为 None
或者是一个默认值的 iterable 。如果一个默认值域必须跟其他没有默认值的域在一起出现,defaults 就应用到最右边的参数。比如如果域名 ['x', 'y', 'z']
和默认值 (1, 2)
,那么 x
就必须指定一个参数值 ,y
默认值 1
, z
默认值 2
。
如果 module 值有定义,命名元组的 __module__
属性值就被设置。
命名元组实例没有字典,所以它们要更轻量,并且占用更小内存。
>>> # 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)
命名元组尤其有用于赋值 csv
sqlite3
模块返回的元组
EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')
import csv
for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):
print(emp.name, emp.title)
import sqlite3
conn = sqlite3.connect('/companydata')
cursor = conn.cursor()
cursor.execute('SELECT name, age, title, department, paygrade FROM employees')
for emp in map(EmployeeRecord._make, cursor.fetchall()):
print(emp.name, emp.title)
除了继承元组的方法,命名元组还支持三个额外的方法和两个属性。为了防止字段名冲突,方法和属性以下划线开始。
somenamedtuple.
_make
(iterable)
类方法从存在的序列或迭代实例创建一个新实例。
>>> t = [11, 22]
>>> Point._make(t)
Point(x=11, y=22)
somenamedtuple.
_asdict
()
返回一个新的 dict
,它将字段名称映射到它们对应的值:
>>> p = Point(x=11, y=22)
>>> p._asdict()
{'x': 11, 'y': 22}
在 3.1 版更改: 返回一个 OrderedDict
而不是 dict
。
在 3.8 版更改: 返回一个常规 dict
而不是 OrderedDict
。 因为自 Python 3.7 起,常规字典已经保证有序。 如果需要 OrderedDict
的额外特性,推荐的解决方案是将结果转换为需要的类型: OrderedDict(nt._asdict())
。
somenamedtuple.
_replace
(**kwargs)
返回一个新的命名元组实例,并将指定域替换为新的值
>>> p = Point(x=11, y=22)
>>> p._replace(x=33)
Point(x=33, y=22)
>>> for partnum, record in inventory.items():
... inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())
somenamedtuple.
_fields
字符串元组列出了字段名。用于提醒和从现有元组创建一个新的命名元组类型。
>>> 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)
somenamedtuple.
_field_defaults
字典将字段名称映射到默认值。
>>> Account = namedtuple('Account', ['type', 'balance'], defaults=[0])
>>> Account._field_defaults
{'balance': 0}
>>> Account('premium')
Account(type='premium', balance=0)
要获取这个名字域的值,使用 getattr()
函数 :
>>> getattr(p, 'x')
11
转换一个字典到命名元组,使用 ** 两星操作符 (所述如 解包参数列表):
>>> d = {'x': 11, 'y': 22}
>>> Point(**d)
Point(x=11, y=22)