Pickle 的序列化与反序列化
- 序列化 (Serialization):将 Python 物件转换为二进制格式,便于储存或传输。
- 反序列化 (Deserialization):将二进制格式的资料还原为原本的 Python 物件。更多内容Python 序列化Serialization and 反序列化Deserialization
什么是 Pickle?
Pickle 是 Python 提供的一个内建模组,专门用于将 Python 物件序列化(serialize)和反序列化(deserialize)。它将 Python 物件转换为二进制格式,便于储存到档案或传输到网路上,并且能够随时还原成原始的 Python 物件。
Pickle 的主要用途
- 储存 Python 物件到档案:将变数(如列表、字典、类别等)储存到磁盘,以便在未来的程式执行中重复使用。
- 物件的网路传输:将 Python 物件序列化后,可以透过网路传输并在接收端反序列化还原。
- 保存程式状态:在某些情况下,可以用来保存程式的中间状态,稍后继续执行。
如何使用 Pickle?
import pickle
# 要储存的物件
data = {"name": "Alice", "age": 30, "languages": ["Python", "C++", "Java"]}
# 打开档案,以二进制写入模式(wb)
with open("data.pkl", "wb") as file:
pickle.dump(data, file)
print("资料已序列化并储存到档案 data.pkl")
# 打开档案,以二进制读取模式(rb)
with open("data.pkl", "rb") as file:
loaded_data = pickle.load(file)
print("从档案中还原的资料:", loaded_data)
pickle常见情境:
- 中间处理结果的保存和读取(如数据分析中的数据快取)。
- 机器学习中训练后的模型保存(如 scikit-learn 使用 pickle 保存模型)。
- 保存状态以供另一个程序读取。
- 透过网路或管道传递序列化的物件。
保存和还原工作进度如果程式执行需要很长时间,pickle 可用于保存执行的中间状态,避免重复执行相同的操作。例如:长时间运行的数据处理工作中保存进度,然后在程序崩溃或中断时还原。
快速测试或临时保存在开发和测试中,pickle 可以用来临时保存数据以快速调试或测试功能。
使用 pickle 的注意事项
安全性问题:pickle 无法防范恶意数据,因此不要反序列化(pickle.load)不受信任的来源的数据。与 JSON 的选择:
当数据只包含基本类型(如字典、列表、数字、字符串等)时,应优先使用 JSON,因为 JSON 可读性高且跨语言支持。若数据包含复杂 Python 特定结构(如自订类别或函数),可使用 pickle。
什么时候不应该使用 pickle?
- 需要跨语言操作:如果需要和非 Python 程序共享数据,应使用 JSON 或其他标準格式。
- 需要数据长期保存:如果数据需要长期保存或存入资料库,pickle 并不是最佳选择,因为它受 Python 版本影响且可读性差。
Shelve
shelve 是 Python 标準库中一个方便的模组,用于将 Python 物件存储到一个类似字典的持久化对象中。它结合了 pickle 的序列化能力和简单的键值存取方式,使得开发者可以轻鬆地保存和读取 Python 的数据结构到文件中,而不需要自己处理文件操作和序列化细节。
shelve 的特点
- 用法和字典类似,可以透过键值对储存和读取数据。
- 使用时只需记住操作字典的方法,例如 db[key] = value。
- 支持将多种类型的 Python 物件(如字典、列表、自定义对象)直接保存到档案中,底层使用 pickle 处理序列化。
- 数据保存在硬盘文件中,程序重启后仍能读取。
- 因为只在需要时加载数据,对于大数据集,比 JSON 或单一 pickle 文件更有效。
- 只能使用字符串作为键。
- 存储的对象需可被 pickle 序列化。
- 与数据库的设计不同,适用于简单数据存储而非高併发操作。
基本使用范例
import shelve
# 开启一个 shelve 档案
with shelve.open("mydata") as db:
# 储存数据
db["name"] = "Alice"
db["age"] = 30
db["skills"] = ["Python", "C++", "Java"]
# 从档案中读取数据
print(db["name"]) # 输出: Alice
print(db["age"]) # 输出: 30
print(db["skills"]) # 输出: [\'Python\', \'C++\', \'Java\']
储存格式 | 类似字典的档案 | 二进制档案 | 文本档案 | 数据库档案 |
可读性 | 低 | 低 | 高 | 高 |
数据类型支持 | 任意 Python 对象 | 任意 Python 对象 | 基本数据类型 | 基本数据类型 |
操作方式 | 类似字典 | 程序控制序列化/反序列化 | 程序控制序列化/反序列化 | SQL 操作 |
应用场景 | 小型数据持久化存储 | 任意序列化需求 | 跨语言数据传输 | 结构化数据存储 |