共计 2350 个字符,预计需要花费 6 分钟才能阅读完成。
1. 什么是 Pickle?
Pickle 是 Python 标准库中的一个模块,专门用于 序列化 和反序列化 Python 对象。Python 标准库中的一个模块,简单来说:
- 序列化(Pickling):将 Python 对象(如列表、字典、类实例等)转换为字节流(二进制数据),方便存储到文件或通过网络传输。
- 反序列化(Unpickling):将字节流还原为原始的 Python 对象。
Pickle 支持几乎所有的 Python 数据类型(包括自定义类),但它是 Python 特有的,不能直接与其他编程语言兼容。
2. 核心功能与基本用法
2.1 保存对象到文件(序列化)
使用 pickle.dump()
将对象保存到文件:
import pickle
data = {"name": "Alice", "age": 30, "scores": [85, 92, 88]}
with open("data.pkl", "wb") as f: # 必须用二进制写入模式('wb')pickle.dump(data, f)
2.2 从文件加载对象(反序列化)
使用 pickle.load()
读取文件并还原对象:
with open("data.pkl", "rb") as f: # 必须用二进制读取模式('rb')loaded_data = pickle.load(f)
print(loaded_data) # 输出:{'name': 'Alice', 'age': 30, 'scores': [85, 92, 88]}
2.3 直接处理字节数据(不保存到文件)
pickle.dumps()
:将对象转换为字节流(不写入文件)。pickle.loads()
:从字节流还原对象。
# 序列化为字节流
bytes_data = pickle.dumps(data)
print(bytes_data) # 输出:b'\x80\x04\x95...'
# 反序列化
restored_data = pickle.loads(bytes_data)
3. 进阶用法
3.1 保存多个对象到同一文件
通过多次调用 dump()
,可将多个对象依次存入文件,读取时需按顺序调用 load()
:
# 保存
with open("multi_data.pkl", "wb") as f:
pickle.dump([1, 2, 3], f)
pickle.dump({"a": "apple", "b": "banana"}, f)
# 读取
with open("multi_data.pkl", "rb") as f:
list_data = pickle.load(f) # 输出:[1, 2, 3]
dict_data = pickle.load(f) # 输出:{'a': 'apple', 'b': 'banana'}
3.2 自定义类的序列化
Pickle 可以序列化自定义类实例,但需确保反序列化时类定义已存在:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# 创建实例并保存
p = Person("Bob", 25)
with open("person.pkl", "wb") as f:
pickle.dump(p, f)
# 读取实例
with open("person.pkl", "rb") as f:
p_loaded = pickle.load(f)
print(p_loaded.name) # 输出:Bob
4. 协议版本(Protocol)
Pickle 支持不同协议版本(影响序列化的效率和兼容性):
- 默认协议:Python 3 默认使用协议 3(高效二进制格式)。
- 指定协议:通过
protocol
参数选择(例如protocol=4
支持更大对象)。
# 使用最高协议版本保存
with open("data_high_protocol.pkl", "wb") as f:
pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
5. 应用场景
- 保存机器学习模型:如训练好的 Scikit-learn 模型。
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X_train, y_train)
# 保存模型
with open("model.pkl", "wb") as f:
pickle.dump(model, f)
- 缓存中间结果:避免重复计算耗时任务。
- 跨程序传递复杂数据:例如将预处理后的数据集传递给另一个脚本。
6. 注意事项
- 安全性 :Pickle 反序列化时会执行任意代码, 不要加载来源不明的
.pkl
文件! - 跨版本兼容性:不同 Python 版本的协议可能存在差异,尽量使用相同环境。
- 文件模式必须为二进制:
'wb'
用于保存,'rb'
用于加载,否则会报错。
7. Pickle 的优缺点
优点 |
缺点 |
支持几乎所有 Python 对象类型(包括自定义类)。 |
仅限 Python 使用,无法跨语言兼容。 |
序列化后的数据紧凑,适合存储复杂结构。 |
序列化后的二进制数据不可读(不同于 JSON)。 |
使用简单,无需手动处理数据类型转换。 |
存在安全风险,反序列化可能执行恶意代码。 |
8. 常见问题示例
8.1 为什么文件要使用二进制模式?
# 错误写法(文本模式会导致编码错误)with open("data.pkl", "w") as f:
pickle.dump(data, f) # 报错:write() 需要字节流,而非字符串
8.2 如何解决反序列化时找不到类定义?
如果反序列化时类 Person
未定义,会抛出 AttributeError
。确保类定义在反序列化代码中可用。
总结
Pickle 是 Python 中处理对象持久化的强大工具,尤其适合保存复杂数据结构和模型。使用时需注意安全性和版本兼容性,结合具体场景选择是否替代 JSON 或其他序列化方案。通过上述示例和知识点,你可以快速掌握其核心用法!
正文完