Python 记录、结构体和纯数据对象
Python 中有多种数据类型可以用来存储复杂的数据结构。在这些类型中,我们可以使用记录 (record)、结构体 (struct) 和纯数据对象 (plain data object) 来表示真实世界的实体或数据集合。
记录 (Record)
定义记录
在 Python 中,我们可以使用字典 (dictionary) 和命名元组 (namedtuple) 来定义记录。
使用字典时,我们可以将不同的属性作为键,将它们的值作为值,在一个字典中组织起来。
person = {
"name": "Alice",
"age": 28,
"gender": "female",
"email": "alice@example.com"
}
而对于有名的属性,我们可以使用命名元组来定义记录。命名元组是一个普通元组的子类,它的每个实例都可以像一个普通对象那样访问它的属性。
from collections import namedtuple
Person = namedtuple("Person", ["name", "age", "gender", "email"])
person = Person("Alice", 28, "female", "alice@example.com")
访问记录
对于字典,我们可以使用键来访问其中的值。
name = person["name"]
而对于命名元组,我们可以使用它的属性来访问其中的值。
name = person.name
结构体 (Struct)
定义结构体
结构体是一种将字节串拆分成一个有意义的序列的方法。在 Python 中,我们可以使用 struct
函数来定义和编码/解码结构体。对于不同的数据类型,需要使用不同的格式化字符串 (format string) 来定义它们。
import struct
# 定义格式化字符串
format_string = "<2ihd"
# 定义结构体
class Point:
def __init__(self, x, y, is_visible, distance):
self.x = x
self.y = y
self.is_visible = is_visible
self.distance = distance
def pack(self):
# 编码数据
return struct.pack(format_string, self.x, self.y, self.is_visible, self.distance)
@classmethod
def unpack(cls, data):
# 解码数据
x, y, is_visible, distance = struct.unpack(format_string, data)
return cls(x, y, is_visible, distance)
编码/解码结构体
我们可以将一个结构体编码为二进制数据 (bytes),或者将二进制数据解码为一个结构体。
# 创建结构体
point = Point(1, 2, True, 3.14)
# 编码结构体
data = point.pack()
# 解码结构体
decoded_point = Point.unpack(data)
纯数据对象 (Plain Data Object)
定义纯数据对象
纯数据对象是一种与 Python 类无关的数据结构,它只由数据组成,没有任何行为。在 Python 中,我们可以使用 dataclass
来轻松定义纯数据对象。
from dataclasses import dataclass
@dataclass
class Rectangle:
width: float
height: float
is_visible: bool = True
上面的代码定义了一个矩形对象,它由宽度、高度和是否可见属性构成。
使用纯数据对象
我们可以像使用普通对象那样来使用纯数据对象。
# 创建矩形对象
rectangle = Rectangle(3.0, 4.0)
# 修改矩形对象
rectangle.is_visible = False
# 访问矩形对象的属性
width = rectangle.width
示例说明
示例 1: 学生记录
假设我们要定义一个学生记录,它包含学生的姓名、年龄、所在地区和联系方式。我们可以用字典和命名元组来定义这个记录。
# 定义学生记录
student_dict = {
"name": "Alice",
"age": 18,
"area": "Zhejiang",
"contact": {
"phone": "123456",
"email": "alice@example.com"
}
}
Student = namedtuple("Student", ["name", "age", "area", "contact"])
student_tuple = Student("Alice", 18, "Zhejiang", {"phone": "123456", "email": "alice@example.com"})
示例 2: 整数数组
假设我们要传输一个整数数组,我们可以使用结构体来编码和解码这个数组。
import struct
# 定义格式化字符串
format_string = "<i"
# 定义整数数组
numbers = [1, 2, 3, 4, 5]
# 编码整数数组
encoded_data = b"".join(struct.pack(format_string, n) for n in numbers)
# 解码整数数组
decoded_data = [struct.unpack(format_string, encoded_data[i:i+4])[0] for i in range(0, len(encoded_data), 4)]