Python namedtuple

时间:2020-02-23 14:43:04  来源:igfitidea点击:

Python namedtuple对象是collections模块的一部分。
Python namedtuple是tuple的扩展。

Python namedtuple

  • Python namedtuple是不变的,就像tuple一样。

  • Namedtuple允许我们为元素提供名称。
    因此,我们可以按索引值或者按名称访问元素。

  • Python namedtuple可帮助我们编写更好的可读性代码。
    如果元组有很多值,则使用索引会造成混乱。
    使用namedtuple,我们可以为字段提供描述性名称。

  • Python namedtuple字段名称可以是任何有效的Python标识符。
    有效标识符由字母,数字和下划线组成,但不能以下划线或者数字开头。
    同样,我们不能使用诸如class,for,def,return,global,pass或者raise等关键字。

  • 我们可以在定义namedtuple时使用defaults参数为namedtuple参数指定默认值。
    请注意,此功能已在Python 3.7中添加。

  • Python namedtuple实例没有按实例的字典,因此它们是轻量级的,并且比常规元组不需要更多的内存。

快速访问元组

在开始namedtuple示例之前,让我们快速看一下python tuple。
我们将创建一些元组并将其值打印到控制台。

emp1 = ('hyman', 35, 'Editor')
emp2 = ('David', 40, 'Author')

for p in [emp1, emp2]:
  print(p)

for p in [emp1, emp2]:
  print(p[0], 'is a', p[1], 'years old working as', p[2])

# pythonic way
for p in [emp1, emp2]:
  print('%s is a %d years old working as %s' % p)

输出:

('hyman', 35, 'Editor')
('David', 40, 'Author')
hyman is a 35 years old working as Editor
David is a 40 years old working as Author
hyman is a 35 years old working as Editor
David is a 40 years old working as Author

请注意,我们正在使用索引来检索元组元素。

Python namedtuple示例

Python namedtuple是使用collections模块中的工厂方法创建的。
该函数签名如下:

collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)
  • typename:这是namedtuple对象的名称。

  • field_names:这是在namedtuple中定义字段名称的第二个参数。
    我们可以使用以下格式来定义它们-"名称年龄角色","名称,年龄,角色"或者" ['名称","年龄","角色"]"。

  • rename:我们可以将重命名指定为True,以便将无效字段重命名为其索引名称。
    例如,"名称定义类"将重命名为"名称"," _ 1"," _ 2""。

  • 默认值:用于将默认值定义为可选参数。
    由于具有默认值的字段必须位于任何没有默认值的字段之后,因此默认值将应用于最右边的参数。
    例如,如果字段名是" ['a"," b"," c"]],而"默认值"是(1、2),则" a"将是必填参数," b"将默认为1," c"默认为2。

  • module:如果定义了module,则命名元组的__module__属性设置为该值。
    此参数在Python 3.6版本中引入。

让我们看一个简单的示例,创建namedtuple并打印其值。

from collections import namedtuple

Employee = namedtuple('Employee', ['name', 'age', 'role'])

# below are also valid ways to namedtuple
# Employee = namedtuple('Employee', 'name age role')
# Employee = namedtuple('Employee', 'name,age,role')

emp1 = Employee('hyman', 35, 'Editor')
emp2 = Employee(name='David', age=40, role='Author')

for p in [emp1, emp2]:
  print(p)

# accessing via index value
for p in [emp1, emp2]:
  print('%s is a %d years old working as %s' % p)

# accessing via name of the field
for p in [emp1, emp2]:
  print(p.name, 'is a', p.age, 'years old working as', p.role)

注意,我正在使用namedtuple字段名称来检索值。
它或者多或者少与以前的元组示例程序几乎相同。

输出:

Employee(name='hyman', age=35, role='Editor')
Employee(name='David', age=40, role='Author')
hyman is a 35 years old working as Editor
David is a 40 years old working as Author
hyman is a 35 years old working as Editor
David is a 40 years old working as Author

带有无效键的Python namedtuple并重命名

如果我们对命名元组名称使用无效的键,那么将得到ValueError

try:
  Person = namedtuple('Person', 'def class')
except ValueError as error:
  print(error)

输出:

Type names and field names cannot be a keyword: 'def'

现在让我们看看将重命名指定为True时会发生什么。

# rename=True will rename invalid names to index value with underscore prefix
Person = namedtuple('Person', 'name def class', rename=True)
print(Person._fields)

输出:

('name', '_1', '_2')

请注意,字段名称已更改为其索引值,并带有下划线前缀。

Python namedtuple模块

# namedtuple module parameter - introduced in 3.6
Person = namedtuple('Person', 'name', module='MyPersonModule')
print(Person.__module__)

输出:

MyPersonModule

Python namedtuple其他方法

我们来看一下可用于namedtuple的三种其他方法。

_make(可迭代)

该类方法可用于从可迭代对象创建namedtuple。

t = ('Lisa', 35, 'Contributor')
emp3 = Employee._make(t)
print(emp3)

输出:

Employee(name='Lisa', age=35, role='Contributor')

_asdict()

这用于从namedtuple创建OrderedDict实例。

od = emp3._asdict()
print(od)

输出:

OrderedDict([('name', 'Lisa'), ('age', 35), ('role', 'Contributor')])

_replace(** kwargs)

Python namedtuple是不可变的,因此我们无法更改其值。
此方法返回namedtuple的新实例,用新值替换指定的字段。

emp3 = emp3._replace(name='Lisa Tamaki', age=40)
print(emp3)

输出:

Employee(name='Lisa Tamaki', age=40, role='Contributor')

Python namedtuple附加属性

namedtuple中有两个附加参数-_fields和_fields_defaults。
顾名思义,它们提供有关字段及其默认值的信息。
Python 3.7删除了_source属性。

print(emp3._fields)
Gender = namedtuple('Gender', 'gender')
Person = namedtuple('Person', Employee._fields + Gender._fields)
print(Person._fields)

# _fields_defaults - introduced in Python 3.7
# Python 3.7 removed verbose parameter and _source attribute

Person1 = namedtuple('Person1', ['name', 'age'], defaults=['hyman', 20])
print(Person1._fields_defaults)

输出:

('name', 'age', 'role')
('name', 'age', 'role', 'gender')
{'name': 'hyman', 'age': 20}

Python namedtuple其他示例

让我们看一下namedtuple的一些其他示例。

getattr()

我们也可以使用getattr()函数获取namedtuple字段值。

emp3_name = getattr(emp3, 'name')
print(emp3_name)

输出:

Lisa Tamaki

字典命名元组

命名元组和Dict非常相似,因此也难怪有一种将dict转换为namedtuple的快速方法。

d = {'age': 10, 'name': 'hyman', 'role':'CEO'}
emp4 = Employee(**d)
print(d)
print(emp4)

输出:

{'age': 10, 'name': 'hyman', 'role': 'CEO'}
Employee(name='hyman', age=10, role='CEO')