Python namedtuple 详解:从基础用法到高级特性

拾光
拾光
发布时间:2026-10-13| 6人浏览过
原创

本文深入解析Python中namedtuple的使用。介绍其作为collections模块中不可变序列类型的核心优势,包括通过属性名直观访问数据。详细讲解namedtuple()构造函数参数、_make()、_asdict()、_replace()及_fields等常用方法,并结合字典构建、CSV/数据库处理及类继承等实际场景提供代码示例。

namedtuple 概述

namedtuple是Python标准库中用于存储数据的一种特殊数据结构,与常见的list和tuple类似。与list不同,namedtuple中的元素是不可变的,这使得它在需要作为字典键或保持数据完整性时非常有用。

namedtuple的核心概念

namedtuple类定义在collections模块中。使用namedtuple可以让代码通过属性名访问数据,从而提升代码的可读性和可维护性。它创建了一种类似元组的数据类型,既支持索引访问和迭代,又允许通过属性名直接获取字段值。

接下来本文将详细介绍Python namedtuple()的具体用法,并通过实例进行演示。

基本定义与参数

基本定义

调用collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)来创建命名元组。

该函数返回一个名为typename的新元组子类。

这个新子类用于创建类似元组的对象,其字段既可以通过属性查找访问,也可以通过索引和迭代方式访问,字段名由field_names指定。

typename参数说明

typename表示生成的子类的名称,类似于C++、Python或Java中的类名。

field_names参数说明

field_names是一个字符串序列,例如['x', 'y']。

field_names也可以是一个包含空格或逗号分隔的单个字符串,例如'x y'或'x, y'。

其他参数说明

其他参数如rename、defaults和module并不常用,此处不再赘述。

常用方法详解

基本样例


from collections import namedtuple
 
# 基本例子
Point = namedtuple('Point',['x','y']) # 类名为Point,属性有'x'和'y'
 
p = Point(11, y=22) # 用位置或关键字参数实例化,因为'x'在'y'前,所以x=11,和函数参数赋值一样的
print(p[0]+p[1]) # 我们也可以使用下标来访问
# 33
 
x, y = p # 也可以像一个元组那样解析
print(x,y)
# (11, 22)
 
print(p.x+p.y) # 也可以通过属性名来访问
# 33
 
print(p) # 通过内置的__repr__函数,显示该对象的信息
# Point(x=11, y=22)

使用somenamedtuple._make(iterable)类方法。

该方法允许从一个序列或可迭代对象中直接对field_names中的属性进行赋值,并返回一个对象实例。


t = [11, 22] # 列表 list
p = Point._make(t) # 从列表中直接赋值,返回对象
print(Point(x=11, y=22))
# Point(x=11, y=22)

使用somenamedtuple._asdict()类方法。

如前所述,namedtuple虽然本质是元组,但其行为更像是一个带有名称的字典。

我们可以直接使用_asdict()方法将其解析为标准的字典dict对象。


p = Point(x=11, y=22) # 新建一个对象
d = p._asdict() # 解析并返回一个字典对象
print(d)
# {'x': 11, 'y': 22}

使用somenamedtuple._replace(**kwargs)类方法。

该方法用于修改某些属性的值,从replace一词即可看出其意图。

需要注意的是,该函数返回的是一个全新的对象,而不会修改原始对象。


p = Point(x=11, y=22) # x=11,y=22
print(p)
# Point(x=11, y=22)
 
d = p._replace(x=33) # x=33,y=22 新的对象
print(p)
# Point(x=11, y=22)
print(d)
# Point(x=33, y=22)

使用somenamedtuple._fields类方法。

该方法返回该对象的所有属性名,结果以元组形式呈现。

由于返回的是元组,因此支持加法等操作。


print(p._fields) # 查看属性名
# ('x', 'y')
 
Color = namedtuple('Color', 'red green blue')
Pixel = namedtuple('Pixel', Point._fields + Color._fields) # 新建一个子类,使用多个属性名
q = Pixel(11, 22, 128, 255, 0)
print(q)

使用somenamedtuple._field_defaults类方法。

该方法是Python 3.8新增的功能,由于当前示例环境为3.6,无法直接验证其正确性。

下面给出官方文档中的示例代码。


Account = namedtuple('Account', ['type', 'balance'], defaults=[0])
print(Account._field_defaults)
#{'balance': 0}
print(Account('premium'))
#Account(type='premium', balance=0)

getattr()函数应用

getattr()函数用于动态获取对象的属性值。


print(getattr(p, 'x'))
# 11

通过字典创建namedtuple对象

演示如何从字典构建namedtuple对象。


d = {'x': 11, 'y': 22} # 字典
p = Point(**d) # 双星号是重点
print(p)
# Point(x=11, y=22)

实际应用场景

处理CSV或SQLite3数据

同样可以将从CSV文件或数据库中读取的数据存储到namedtuple中。

在此场景中,每次处理的内容通常是一行数据。


EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')
 
import csv
for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "r"))):
 # 这里每行返回一个对象 注意!
 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)

继承与扩展

类的继承应用

接下来,我们将使用DeepMind开源项目graph_nets中的一段代码来介绍namedtuple的继承用法。


NODES = "nodes"
EDGES = "edges"
RECEIVERS = "receivers"
SENDERS = "senders"
GLOBALS = "globals"
N_NODE = "n_node"
N_EDGE = "n_edge"
 
GRAPH_DATA_FIELDS = (NODES, EDGES, RECEIVERS, SENDERS, GLOBALS)
GRAPH_NUMBER_FIELDS = (N_NODE, N_EDGE)
 
class GraphsTuple(
	# 定义元组子类名 以及字典形式的键名(属性名)
 collections.namedtuple("GraphsTuple",
    GRAPH_DATA_FIELDS + GRAPH_NUMBER_FIELDS)): 
 
	# 这个函数用来判断依赖是否满足,和我们的namedtuple关系不大
	def _validate_none_fields(self):
		"""Asserts that the set of `None` fields in the instance is valid."""
		if self.n_node is None:
		 raise ValueError("Field `n_node` cannot be None")
		if self.n_edge is None:
		 raise ValueError("Field `n_edge` cannot be None")
		if self.receivers is None and self.senders is not None:
		 raise ValueError(
			 "Field `senders` must be None as field `receivers` is None")
		if self.senders is None and self.receivers is not None:
		 raise ValueError(
			 "Field `receivers` must be None as field `senders` is None")
		if self.receivers is None and self.edges is not None:
		 raise ValueError(
			 "Field `edges` must be None as field `receivers` and `senders` are "
			 "None")
 
	# 用来初始化一些参数 不是重点
	def __init__(self, *args, **kwargs):
		del args, kwargs
		# The fields of a `namedtuple` are filled in the `__new__` method.
		# `__init__` does not accept parameters.
		super(GraphsTuple, self).__init__()
		self._validate_none_fields()
 
	# 这就用到了_replace()函数,注意只要修改了属性值
	# 那么就返回一个新的对象
	def replace(self, **kwargs):
		output = self._replace(**kwargs) # 返回一个新的实例 
		output._validate_none_fields() # pylint: disable=protected-access 验证返回的新实例是否满足要求
		return output
 
	# 这是为了针对tensorflow1版本的函数
	# 返回一个拥有相同属性的对象,但是它的属性值是输入的大小和类型
	def map(self, field_fn, fields=GRAPH_FEATURE_FIELDS): # 对每个键应用函数
	"""Applies `field_fn` to the fields `fields` of the instance.
	`field_fn` is applied exactly once per field in `fields`. The result must
	satisfy the `GraphsTuple` requirement w.r.t. `None` fields, i.e. the
	`SENDERS` cannot be `None` if the `EDGES` or `RECEIVERS` are not `None`,
	etc.
	Args:
	 field_fn: A callable that take a single argument.
	 fields: (iterable of `str`). An iterable of the fields to apply
		`field_fn` to.
	Returns:
	 A copy of the instance, with the fields in `fields` replaced by the result
	 of applying `field_fn` to them.
	"""
	return self.replace(**{k: field_fn(getattr(self, k)) for k in fields}) # getattr(self, k) 获取的是键值对中的值, k表示键

到此,关于Python中namedtuple使用的详解文章介绍完毕。更多相关python namedtuple的使用内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。