Python 中的序列化
序列化是指将对象转换为以后可以轻松存储、传输或重建的格式的过程。在 Python 中,这涉及将复杂的数据结构(例如对象或字典)转换为字节流。
我们为什么使用序列化?
序列化允许数据轻松保存到磁盘或通过网络传输,然后重建回其原始形式。它对于保存游戏状态、存储用户首选项或在不同系统之间交换数据等任务非常重要。
Python 中的序列化库
Python 提供了多个用于序列化的库,每个库都有自己的优势。以下是 Python 中一些常用序列化库的详细概述 -
- Pickle - 这是 Python 的内置模块,用于序列化和反序列化 Python 对象。它易于使用,但特定于 Python,如果与不受信任的数据一起使用,可能会产生安全隐患。
- JSON − JSON(JavaScript 对象表示法)是一种轻量级数据交换格式,可读且易于解析。它是 Web API 和跨平台通信的理想选择。
- YAML - YAML:YAML(YAML Ain't Markup Language)是一种人类可读的数据序列化标准,人类和机器也都易于读写。它支持复杂的数据结构,经常在配置文件中使用。
使用 pickle 模块进行序列化
Python 中的 pickle 模块用于序列化和反序列化对象。序列化,也称为 pickling,涉及将 Python 对象转换为字节流,然后可以将其存储在文件中或通过网络传输。
反序列化 或 unpickling 是相反的过程,将字节流转换回 Python 对象。
序列化对象
我们可以使用 dump() 函数序列化对象并将其写入文件。文件必须以二进制写入模式 ('wb') 打开。
例
在以下示例中,将字典序列化并写入名为“data.pkl”的文件中 -
import pickle
data = {'name': 'Alice', 'age': 30, 'city': 'New York'}
# Open a file in binary write mode
with open('data.pkl', 'wb') as file:
# Serialize the data and write it to the file
pickle.dump(data, file)
print ("File created!!")
当执行上述代码时,字典对象的字节表示将存储在 data.pkl 文件中。
反序列化对象
要反序列化或解封对象,你可以使用 load() 函数。文件必须以二进制读取模式 ('rb') 打开,如下所示 -
import pickle
# Open the file in binary read mode
with open('data.pkl', 'rb') as file:
# Deserialize the data
data = pickle.load(file)
print(data)
这将从 “data.pkl” 中读取字节流并将其转换回原始字典,如下所示 -
Pickle 协议
协议是构造和解构 Python 对象到二进制数据或从二进制数据解构 Python 对象时使用的约定。
pickle 模块支持不同的序列化协议,更高的协议通常会提供更多的功能和更好的性能。目前 pickle 模块定义了 6 种不同的协议,如下所示 -
协议 | 描述 |
---|---|
Protocol version 0 |
原始的 “human-readable” 协议向后兼容早期版本。 |
Protocol version 1 |
旧的二进制格式也与早期版本的 Python 兼容。 |
Protocol version 2 |
在 Python 2.3 中引入,提供了对新式类的高效封存。 |
Protocol version 3 |
在 Python 3.0 中添加。当需要与其他 Python 3 版本兼容时推荐使用。 |
Protocol version 4 |
在 Python 3.4 中引入。它增加了对非常大对象的支持。 |
Protocol version 5 |
在 Python 3.8 中引入。它增加了对带外数据的支持。 |
您可以通过将协议作为参数传递给 pickle.dump() 函数来指定协议。
要了解 Python 安装的最高和默认协议版本,请使用 pickle 模块中定义的以下常量 -
>>> import pickle
>>> pickle.HIGHEST_PROTOCOL
5
>>> pickle.DEFAULT_PROTOCOL
4
Pickler 和 Unpickler 类
Python 中的 pickle 模块还定义了 Pickler 和 Unpickler 类,以便更详细地控制序列化和反序列化过程。“Pickler” 类将 pickle 数据写入文件,而 “Unpickler” 类从文件中读取二进制数据并重建原始 Python 对象。
使用 Pickler 类
要使用 Pickler 类序列化 Python 对象,您可以按照以下步骤操作 -
from pickle import Pickler
# Open a file in binary write mode
with open("data.txt", "wb") as f:
# Create a dictionary
dct = {'name': 'Ravi', 'age': 23, 'Gender': 'M', 'marks': 75}
# Create a Pickler object and write the dictionary to the file
Pickler(f).dump(dct)
print ("Success!!")
执行上述代码后,字典对象的字节表示将存储在 “data.txt” 文件中。
使用 Unpickler 类
要使用 Unpickler 类从二进制文件反序列化数据,可以执行以下操作 -
from pickle import Unpickler
# Open the file in binary read mode
with open("data.txt", "rb") as f:
# Create an Unpickler object and load the dictionary from the file
dct = Unpickler(f).load()
# Print the dictionary
print(dct)
我们得到的输出如下 -
封存自定义类对象
pickle 模块还可以序列化和反序列化自定义类。类定义在 pickling 和 unpickling 时都必须可用。
例在此示例中,对 “Person” 类的实例进行序列化,然后进行反序列化,从而保持对象的状态 -
import pickle
class Person:
def __init__(self, name, age, city):
self.name = name
self.age = age
self.city = city
# Create an instance of the Person class
person = Person('Alice', 30, 'New York')
# Serialize the person object
with open('person.pkl', 'wb') as file:
pickle.dump(person, file)
# Deserialize the person object
with open('person.pkl', 'rb') as file:
person = pickle.load(file)
print(person.name, person.age, person.city)
执行上述代码后,我们得到以下输出 -
Python 标准库还包括 marshal 模块,该模块用于 Python 对象的内部序列化。与专为通用用途而设计的 pickle 不同,marshal 主要供 Python 本身使用(例如,用于编写 .pyc 文件)。
由于 Python 版本之间可能存在兼容性问题,因此通常不建议将其用于通用序列化。
使用 JSON 进行序列化
JSON(JavaScript 对象表示法)是一种流行的数据交换格式。它是人类可读的,易于编写且独立于语言,使其成为序列化的理想选择。
Python 通过 json 模块提供对 JSON 的内置支持,该模块允许您将数据序列化为 JSON 格式或从 JSON 格式反序列化数据。
序列化
序列化是将 Python 对象转换为 JSON 字符串或将其写入文件的过程。
示例:将数据序列化为 JSON 字符串
在下面的示例中,我们使用 json.dumps() 函数将 Python 字典转换为 JSON 字符串 -
import json
# Create a dictionary
data = {"name": "Alice", "age": 25, "city": "San Francisco"}
# Serialize the dictionary to a JSON string
json_string = json.dumps(data)
print(json_string)
以下是上述代码的输出 -
示例:序列化数据并写入文件
在这里,我们使用 json.dump() 函数将序列化的 JSON 数据直接写入文件 -
import json
# Create a dictionary
data = {"name": "Alice", "age": 25, "city": "San Francisco"}
# Serialize the dictionary and write it to a file
with open("data.json", "w") as f:
json.dump(data, f)
print ("Success!!")
反序列化
反序列化是将 JSON 字符串转换回 Python 对象或从文件中读取它的过程。
示例:反序列化 JSON 字符串
在以下示例中,我们使用 json.loads() 函数将 JSON 字符串转换回 Python 字典 -
import json
# JSON string
json_string = '{"name": "Alice", "age": 25, "city": "San Francisco"}'
# Deserialize the JSON string into a Python dictionary
loaded_data = json.loads(json_string)
print(loaded_data)
它将产生以下输出 -
示例:从文件中反序列化数据
在这里,我们使用 json.load() 函数从文件中读取 JSON 数据并将其转换为 Python 字典 -
import json
# Open the file and load the JSON data into a Python dictionary
with open("data.json", "r") as f:
loaded_data = json.load(f)
print(loaded_data)
获得的输出如下 -
使用 YAML 进行序列化
YAML (YAML Ain't Markup Language) 是一种人类可读的数据序列化标准,通常用于配置文件和数据交换。
Python 通过 pyyaml 包支持 YAML 序列化和反序列化,需要先安装,如下所示 -
示例:序列化数据并写入 YAML 文件
在下面的示例中,yaml.dump() 函数将 Python 字典数据转换为 YAML 字符串,并将其写入文件 “data.yaml”。
“default_flow_style”参数可确保 YAML 输出在扩展格式下更具人类可读性 -
import yaml
# Create a Python dictionary
data = {"name": "Emily", "age": 35, "city": "Seattle"}
# Serialize the dictionary and write it to a YAML file
with open("data.yaml", "w") as f:
yaml.dump(data, f, default_flow_style=False)
print("Success!!")
示例:从 YAML 文件反序列化数据
在这里,yaml.safe_load() 函数用于安全地从“data.yaml”加载 YAML 数据并将其转换为 Python 字典 (loaded_data) -
import yaml
# Deserialize data from a YAML file
with open("data.yaml", "r") as f:
loaded_data = yaml.safe_load(f)
print(loaded_data)
生成的输出如下所示 -