当我们需要定义一个不可变的数据结构,这时可以使用Python命名元组(namedtuple)。
命名元组是一个类似于元组的类,它有一个固定的字段数量和不可变性,但是每个元素都有一个特定的名称。这使得代码更加易懂和易读,并且可以替代使用元组或字典的情况。
定义命名元组
Python中,内置的collections
模块提供了namedtuple
的定义方式,使用方法如下:
from collections import namedtuple
# 定义一个Person类型,包括name、age两个字段
Person = namedtuple('Person', ['name', 'age'])
上述代码定义了一个名为Person
的命名元组类型,它有两个字段name
和age
,可以像下面这样使用:
# 创建一个Person对象
p = Person('Tom', 20)
# 访问p对象的name和age字段
print(p.name)
print(p.age)
输出结果为:
Tom
20
命名元组访问数据
使用命名元组,可以像访问普通类的属性一样来访问元组的元素。
# 定义一个Person类型,包括name、age两个字段
Person = namedtuple('Person', ['name', 'age'])
# 创建一个Person对象
p = Person('Tom', 20)
# 访问p对象的name和age字段
print(p.name)
print(p.age)
使用命名元组收集数据
命名元组的另一个用途是收集数据,我们可以定义一个命名元组类型,将多个数据作为属性收集在一起。
from collections import namedtuple
# 定义一个Grade类型,包括语文、数学和英语三个字段
Grade = namedtuple('Grade', ['Chinese', 'Math', 'English'])
# 定义一个Student类型,包括姓名name和Grade对象score两个字段
Student = namedtuple('Student', ['name', 'score'])
上述代码定义了一个名为Student
的命名元组类型,它有两个字段name
和score
,其中score
又是一个命名元组类型,包括Chinese
、Math
和English
三个字段。
下面创建一个Student
对象:
# 创建一个Student对象
s = Student('Tom', Grade(80, 70, 90))
# 访问s对象的name和score字段
print(s.name)
print(s.score)
# 访问s对象的score对象的Chinese字段
print(s.score.Chinese)
输出结果为:
Tom
Grade(Chinese=80, Math=70, English=90)
80
命名元素减少内存开销
如果有大量实例的命名元素对象需要创建, namedtuple 可以带来内存和性能方面的优势,这是因为他们不需要像普通类实例那样支持写入操作。 如果需要一个可以更改的属性值,则可以通过namedtuple实例._replace()方法进行更改,它会创建一个新实例,并将值替换到原有实例的字段中。
下面代码记录了一段程序的状态,包括程序名称、运行总时间、最后运行时间:
from collections import namedtuple
import time
# 定义Program类型,包括name、total_time、last_time三个字段
Program = namedtuple('Program', ['name', 'total_time', 'last_time'])
# 创建一些Program对象
programs = []
programs.append(Program('program1', 10, time.time()))
programs.append(Program('program2', 20, time.time()))
programs.append(Program('program3', 30, time.time()))
# 修改其中一个Program的total_time属性
programs[1] = programs[1]._replace(total_time=25)
# 输出所有Program对象
for p in programs:
print(p)
输出结果为:
Program(name='program1', total_time=10, last_time=1651942849.1599433)
Program(name='program2', total_time=25, last_time=1651942849.1599677)
Program(name='program3', total_time=30, last_time=1651942849.159972)
注意,可以通过_replace
方法,创建一个新的命名元素实例,用于替换当前实例中的某些字段。
以上就是Python命名元组收集数据的完整攻略,可以将数据沉淀到命名元组中,方便读取、使用,同时,命名元组也可以减少内存开销,提高程序性能。