Python3 Pickle 模块
序列化(持久化)是把内存中的对象变成可保存或可传输的字节流,之后还能还原成对象。pickle 模块是 Python 专属的序列化方案:几乎任何 Python 对象都能序列化,但它只适用于 Python 程序之间,不能跨语言。
dumps 与 loads:内存中序列化
dumps 把对象变成字节串,loads 把字节串还原成原对象:
import pickle
data = {'name': '张三', 'scores': [90, 85], 'ok': True}
blob = pickle.dumps(data) # 序列化成 bytes
print(blob) # 输出:b'\x80\x05\x95...'(二进制,人不可读)
obj = pickle.loads(blob) # 反序列化还原
print(obj) # 输出:{'name': '张三', 'scores': [90, 85], 'ok': True}
dump 与 load:写入文件
dump 直接写文件(二进制模式 'wb'),load 从文件读回('rb'),适合缓存中间结果、保存训练好的模型:
import pickle
data = {'name': '张三', 'scores': [90, 85]}
with open('data.pkl', 'wb') as f:
pickle.dump(data, f) # 保存到文件
with open('data.pkl', 'rb') as f:
obj = pickle.load(f) # 读回
print(obj) # 输出:{'name': '张三', 'scores': [90, 85]}
支持的对象范围
可序列化:基本类型、列表/字典/元组/集合、自定义类实例,甚至函数与类本身。不可序列化:文件对象、socket、生成器等运行时资源。
import pickle
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
s = Student('小明', 12)
s2 = pickle.loads(pickle.dumps(s)) # 自定义实例可序列化再还原
print(s2.name, s2.age) # 输出:小明 12
安全性警告
永远不要反序列化不可信来源的 pickle 数据。 pickle 还原对象时会执行其中携带的代码,恶意数据可在你的机器上运行任意命令:
import pickle
# 示意:攻击者可把危险对象塞进数据,loads 时即被执行
evil = b'...' # 来自网络/他人的不可信字节流
pickle.loads(evil) # 危险!不要对不可信数据调用 loads
凡是来自网络、邮件或他人提供的 pickle 文件,一律不要 load;对外接收数据请改用 JSON 等安全格式。
与 JSON 对比
| 对比项 | pickle | JSON |
|---|---|---|
| 格式 | Python 私有二进制 | 通用文本 |
| 人可读 | 否 | 是 |
| 跨语言 | 仅 Python | 几乎所有语言 |
| 安全性 | 危险,不可信数据勿 load | 安全 |
| 支持对象 | 几乎全部 Python 对象 | 仅基本类型组合 |
小结
pickle 适合在 Python 内部保存任意对象,记住 dumps/loads(内存)与 dump/load(文件)两组用法即可;它不安全且不跨语言,对外交换数据请用 JSON。