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 对比

对比项pickleJSON
格式Python 私有二进制通用文本
人可读
跨语言仅 Python几乎所有语言
安全性危险,不可信数据勿 load安全
支持对象几乎全部 Python 对象仅基本类型组合

小结

pickle 适合在 Python 内部保存任意对象,记住 dumps/loads(内存)与 dump/load(文件)两组用法即可;它不安全且不跨语言,对外交换数据请用 JSON。

笔记加载中…