\_pickle 和 json 适用场景不同:\_pickle 支持全 python 对象、高效保真但不跨语言且不安全;json 仅支持基础类型、人类可读跨语言安全,适合 api 和配置。

_pickle 和 json 都能实现 Python 对象的序列化,但设计目标、能力边界和适用场景完全不同。选错可能导致程序崩溃、数据丢失或安全风险。
支持的数据类型范围不同
_pickle 是 Python 原生序列化协议,能处理几乎所有 Python 对象:函数、类实例、嵌套对象、自定义类、lambda、甚至带循环引用的结构。它保存的是对象的“状态+类型信息”,反序列化时会重建原对象(包括其方法和行为)。
json 是语言无关的文本格式,只支持有限的内置类型:dict、list、str、int、float、bool、None。遇到 datetime、bytes、set、自定义类等会直接报错。必须手动转换(比如把 datetime 转成 ISO 字符串)。
- _pickle 可以序列化
datetime.now()、re.compile(r'\d+')、threading.Lock()(虽然不推荐) - json 只认得
{"name": "Alice", "scores": [95, 87]}这类纯数据结构
跨语言与可读性差异明显
json 输出是标准 UTF-8 文本,人类可读,其他语言(JavaScript、Go、Java)都能原生解析。适合 API 通信、配置文件、前端交互。
立即学习“Python免费学习笔记(深入)”;
_pickle 输出是二进制字节流,不可读,且只保证在相同 Python 版本和环境下安全反序列化。换版本可能失败,跨语言完全不可用。
- 写配置?用 json —— 编辑器能打开,团队成员能看懂
- 缓存函数中间结果到本地磁盘?用 _pickle —— 快、保真、省事
安全性截然不同
json 是纯数据格式,解析过程不执行代码,天然安全。
_pickle 在反序列化时会动态导入模块、调用类的 __reduce__ 方法,恶意构造的 pickle 数据可执行任意代码。绝不能反序列化不可信来源的数据。
- 用户上传的文件?永远别用 pickle.load() 解析
- 内部服务间短时缓存(如 Redis 存 session)?可用 pickle,但需确保传输链路可信
性能与体积也有实际差距
_pickle(尤其是 protocol=5)通常比 json 更快,生成的二进制数据也更小,尤其对复杂嵌套结构或大量数字/字符串时优势明显。
json 因要转义、加引号、冗余字段名,体积更大,解析也要做类型推断和字符串解析,速度略慢。但差距在普通业务数据中不明显。
- 10 万条带时间戳的日志对象?_pickle 序列化快 2–3 倍,体积小约 30%
- 一个 5 层嵌套的配置字典?json 和 pickle 性能差别不大,可读性更重要










