Python 标准库中 pickle 模块的基本用法

picklePython 标准库里用来做对象序列化反序列化的模块。➡️

  • 序列化:把 Python 对象变成字节流,方便保存到文件
  • 反序列化:把字节流再恢复成原来的 Python 对象

Python 中有

  • 列表、字典、元组、集合
  • 自定义类对象
  • 训练好的模型对象
  • 中间计算结果 等各种对象,怎么存取这些对象?

这个时候就可以用到 pickle 模块。

pickle 可以把 Python 里的对象“打包存盘”,以后再“原样读回来”


1. 基本用法

1.1 保存对象到文件

1
2
3
4
5
6
7
8
9
10
import pickle

data = {
"name": "Alice",
"age": 25,
"scores": [90, 88, 95]
}

with open("data.pkl", "wb") as f:
pickle.dump(data, f)

说明:

  • "wb" 表示以二进制写入
  • pickle.dump(obj, file) 表示把对象写入文件

1.2 从文件读取对象

1
2
3
4
5
6
import pickle

with open("data.pkl", "rb") as f:
data = pickle.load(f)

print(data)

说明:

  • "rb" 表示以二进制读取
  • pickle.load(file) 表示从文件中恢复对象

不写文件,直接转成字节

1.3 对象转字节

1
2
3
4
5
6
import pickle

data = [1, 2, 3, {"a": 10}]
b = pickle.dumps(data)

print(b)

这里:

  • dumps() 返回的是字节对象
  • 末尾有个 s,可以理解为“dump to string/bytes”

1.4 从字节恢复对象

1
2
3
4
5
6
import pickle

b = pickle.dumps([1, 2, 3])
data = pickle.loads(b)

print(data)

这里:

  • loads() 从字节中恢复对象

2. 四个最常用函数

pickle 里最常见的就是这四个:

  • pickle.dump(obj, file) 把对象写到文件

  • pickle.load(file) 从文件读回对象

  • pickle.dumps(obj) 把对象转成字节

  • pickle.loads(bytes_obj) 从字节恢复对象


3. 一个完整的小例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import pickle

students = [
{"name": "Tom", "score": 85},
{"name": "Jerry", "score": 92}
]

# 保存
with open("students.pkl", "wb") as f:
pickle.dump(students, f)

# 读取
with open("students.pkl", "rb") as f:
loaded_students = pickle.load(f)

print(loaded_students)
print(type(loaded_students))

4. 常见应用场景

4.1 保存机器学习模型或中间结果

例如:

1
2
3
4
5
6
import pickle

model = {"weights": [0.1, 0.5, 0.3], "bias": 0.2}

with open("model.pkl", "wb") as f:
pickle.dump(model, f)

4.2 缓存计算结果

某些计算很耗时,可以先保存,下次直接读取。


5. 注意事项

5.1 pickle 文件不是通用格式

它主要给 Python 用,不适合和其他语言交换数据。 如果你想和别的语言或系统交互,通常更适合用:

  • JSON
  • CSV
  • YAML
  • Parquet

5.2 不能随便加载不可信的 .pkl 文件

这是最重要的一点。

pickle.load() 在反序列化时,可能执行恶意代码。 所以:

  • 只加载你自己生成的 .pkl 文件
  • 不要随便打开网上下载的 .pkl 文件

5.3 保存自定义类对象时,pickle 依赖类的模块路径

特别是保存了自定义类对象时,后面改了类定义、模块名或文件结构,旧的 pickle 文件可能不能正常恢复。

这是因为 pickle 保存对象时,通常不会把这个类的方法代码一起完整打包进去,而是主要保存:

  • 对象所属的模块名和类名
  • 对象的属性数据(状态)

比如一个对象原来属于 utils.SimpleProblem,那么在反序列化时,pickle.load() 会尝试:

  1. 重新导入 utils
  2. 找到其中的 SimpleProblem
  3. 再把之前保存的属性恢复到对象里

如果此时:

  • utils.py 被删了
  • SimpleProblem 被移动到别的文件了
  • 类名改了
  • 类结构变了

那么就可能出现类似错误:

1
ModuleNotFoundError: No module named 'utils'

所以要注意:

  • 如果 pickle 里保存的是自定义类对象,后续不要随意改模块路径和类名
  • 如果代码结构已经调整,旧 pickle 文件可能也要重新生成
  • 更稳妥的做法是只保存纯数据(如字典、列表、张量),再手动重建对象

6. 和 JSON 的区别

6.1 pickle

优点:

  • 能保存更多 Python 对象类型
  • 使用方便
  • 适合 Python 内部使用

缺点:

  • 不安全
  • 不通用
  • 可读性差

6.2 json

优点:

  • 通用
  • 文本格式,可读性好
  • 更安全

缺点:

  • 只能保存基本数据类型
  • 不能直接保存很多复杂 Python 对象

7. 什么时候用 pickle

适合:

  • Python 项目内部临时存数据
  • 保存训练中间结果
  • 保存复杂对象结构

不适合:

  • 跨语言数据交换
  • 存长期重要数据
  • 处理不可信来源文件

Python 标准库中 pickle 模块的基本用法
https://nanana-szz.github.io/04-pickle/
作者
John Doe
发布于
2026年4月14日
许可协议