Python Pickle 模块
在 Python 开发中,我们经常需要把运行时的对象保存下来,或者在程序重启后恢复之前的状态,例如:
- 将计算结果缓存到磁盘,避免重复计算
- 保存用户配置、程序中间状态
- 在不同 Python 进程之间传递复杂对象
pickle 模块正是 Python 为解决这类问题提供的官方内置方案。
Python 的 pickle 模块是一个用于序列化和反序列化 Python 对象的标准库模块。
在开始使用 Pickle 之前,需要理解两个核心概念:
- 序列化(Pickling):将 Python 对象转换为字节序列
- 反序列化(Unpickling):将字节序列转换回 Python 对象
pickle 模块可以将几乎所有的 Python 对象(如列表、字典、类实例等)保存到文件中,或者通过网络传输,然后在需要时重新加载。
为什么使用 Pickle 模块?
Section titled “为什么使用 Pickle 模块?”- 数据持久化:将 Python 对象保存到文件中,以便在程序关闭后仍然可以访问这些数据。
- 数据传输:通过网络传输 Python 对象,例如在分布式系统中传递数据。
- 快速存储和加载:
pickle模块可以高效地处理复杂的数据结构,适合需要快速存储和加载的场景。
Pickle 的典型使用场景
Section titled “Pickle 的典型使用场景”pickle 非常适合以下场景:
- 本地数据持久化
- 程序运行状态保存与恢复
- 中间计算结果缓存
- Python 进程间通信(IPC)
- 机器学习模型、特征数据的保存
不适合的场景:
- 跨语言数据交换
- 前后端接口数据传输
- 不可信数据源的反序列化
Pickle 支持哪些对象?
Section titled “Pickle 支持哪些对象?”1. 支持的对象类型
Section titled “1. 支持的对象类型”| 类型 | 是否支持 |
|---|---|
| int / float / bool / str | 支持 |
| list / tuple / dict / set | 支持 |
| None | 支持 |
| 自定义类实例 | 支持 |
| 嵌套结构 | 支持 |
不支持或不推荐的对象
Section titled “不支持或不推荐的对象”- 打开的文件对象
- socket、数据库连接
- 操作系统资源
- 依赖运行环境状态的对象
使用 Pickle 模块非常简单,只需要导入即可:
Pickle 模块的基本用法
Section titled “Pickle 模块的基本用法”1. 序列化对象
Section titled “1. 序列化对象”使用 pickle.dump() 方法可以将 Python 对象序列化并保存到文件中。
'wb'表示以二进制写模式打开文件。pickle.dump()将data对象序列化并写入文件。
2. 反序列化对象
Section titled “2. 反序列化对象”使用 pickle.load() 方法可以从文件中加载并反序列化 Python 对象。
'rb'表示以二进制读模式打开文件。pickle.load()从文件中读取字节流并反序列化为 Python 对象。
3.序列化到字节串
Section titled “3.序列化到字节串”如果不想保存到文件,可以使用 pickle.dumps() 将对象序列化为字节串:
4. 从字节串反序列化
Section titled “4. 从字节串反序列化”使用 pickle.loads() 可以从字节串反序列化对象:
5. 可以序列化的对象类型
Section titled “5. 可以序列化的对象类型”Pickle 可以序列化大多数 Python 对象,包括:
- 基本数据类型:整数、浮点数、字符串、布尔值、None
- 集合类型:列表、元组、字典、集合
- 自定义类的实例
- 函数和类(有一定限制)
6. 序列化自定义类
Section titled “6. 序列化自定义类”Pickle 可以很好地处理自定义类的实例:
7. 序列化多个对象
Section titled “7. 序列化多个对象”可以多次调用 pickle.dump() 来保存多个对象:
8. 实际应用示例
Section titled “8. 实际应用示例”示例1:保存和加载机器学习模型配置
示例2:缓存计算结果
Pickle 模块的注意事项
Section titled “Pickle 模块的注意事项”- 安全性:
pickle模块在反序列化时会执行任意代码,因此不要加载来自不可信来源的pickle数据,以免遭受恶意攻击。 - 兼容性:
pickle生成的字节流是 Python 特有的,不同版本的 Python 之间可能存在兼容性问题。 - 性能:对于大型数据集,
pickle的序列化和反序列化可能会比较慢,可以考虑使用更高效的序列化工具,如json或msgpack。
高级用法:自定义对象的序列化
Section titled “高级用法:自定义对象的序列化”pickle 模块支持自定义类的序列化。默认情况下,pickle 会保存对象的属性和类名。如果需要更复杂的序列化逻辑,可以在类中实现 __getstate__() 和 __setstate__() 方法。
pickle 模块常用方法
Section titled “pickle 模块常用方法”| 方法 | 说明 | 示例 |
|---|---|---|
pickle.dump(obj, file) |
将对象序列化并写入文件 | pickle.dump(data, open('data.pkl', 'wb')) |
pickle.load(file) |
从文件读取并反序列化对象 | data = pickle.load(open('data.pkl', 'rb')) |
pickle.dumps(obj) |
将对象序列化为字节串 | bytes_data = pickle.dumps([1, 2, 3]) |
pickle.loads(bytes) |
从字节串反序列化对象 | lst = pickle.loads(bytes_data) |
pickle.HIGHEST_PROTOCOL |
可用的最高协议版本(属性) | pickle.dump(..., protocol=pickle.HIGHEST_PROTOCOL) |
pickle.DEFAULT_PROTOCOL |
默认协议版本(属性,通常为4) | pickle.dumps(obj, protocol=pickle.DEFAULT_PROTOCOL) |
1. 序列化对象到文件
2. 从文件反序列化
3. 序列化为字节串(网络传输/缓存)
pickle 模块协议版本
Section titled “pickle 模块协议版本”| 协议版本 | 说明 |
|---|---|
| 0 | 人类可读的ASCII格式(兼容旧版) |
| 1 | 二进制格式(兼容旧版) |
| 2 | Python 2.3+ 优化支持类对象 |
| 3 | Python 3.0+ 默认协议(不支持Python 2) |
| 4 | Python 3.4+ 支持更大对象和更多数据类型 |
| 5 | Python 3.8+ 支持内存优化和数据共享 |