← 返回题目列表

Python 中 pickle 和 json 序列化有什么区别?

高频 中等 第 10 / 27 题 更新于 2026/07/27
序列化picklejson安全

简化版

json 是跨语言文本格式,适合接口传输和配置;pickle 是 Python 专用二进制序列化,能保存更多 Python 对象,但不安全,不能反序列化不可信数据。面试重点是兼容性、安全性和可读性差异。

详细版

JSON 示例:

import json

data = {"name": "Tom", "age": 18}
text = json.dumps(data, ensure_ascii=False)
obj = json.loads(text)

pickle 示例:

import pickle

data = {"name": "Tom", "age": 18}
binary = pickle.dumps(data)
obj = pickle.loads(binary)

区别:

对比点jsonpickle
格式文本二进制
跨语言Python 专用
可读性可读不适合人工阅读
支持对象基本数据类型为主支持更多 Python 对象
安全性相对安全反序列化不可信数据危险
典型场景API、配置、日志Python 内部缓存、模型或对象临时保存

使用 pickle 最大的红线:不要加载不可信来源的 pickle 数据,因为反序列化可能执行恶意代码。

完整版教学

一、序列化解决什么问题

内存里的对象不能直接写入文件或通过网络传输,需要转换成某种可保存、可传输的格式。

这个过程叫序列化:

object -> bytes/string

反向过程叫反序列化:

bytes/string -> object

Python 常见序列化方式包括 jsonpicklemarshal、第三方的 msgpack、protobuf 等。

面试最常考的是 jsonpickle

二、json 的特点

JSON 是通用文本格式,跨语言支持很好。

支持的数据类型主要包括:

  • object,对应 Python dict;
  • array,对应 Python list;
  • string;
  • number;
  • boolean;
  • null,对应 Python None。

示例:

import json

text = json.dumps({"ok": True, "items": [1, 2]})
data = json.loads(text)

JSON 很适合接口数据、配置文件、日志数据,因为它可读、通用、容易调试。

三、pickle 的特点

pickle 是 Python 专用序列化协议。

它能处理更多 Python 对象,比如某些自定义类实例:

import pickle

class User:
    def __init__(self, name):
        self.name = name

u = User("Tom")
data = pickle.dumps(u)
u2 = pickle.loads(data)

但 pickle 的可移植性差。它依赖 Python 对象结构、模块路径和类定义。代码结构变了,旧 pickle 文件可能就无法正常加载。

四、pickle 为什么不安全

pickle 反序列化不是简单读取数据,它可能根据数据指令导入模块、调用对象构造逻辑。

如果攻击者构造恶意 pickle,加载时可能执行危险代码。

所以标准建议非常明确:不要反序列化不可信来源的 pickle 数据。

安全边界外的数据交换,优先用 JSON、protobuf 等更适合传输的格式。

五、json 处理自定义对象

JSON 默认不能直接序列化自定义对象:

json.dumps(User("Tom"))  # TypeError

常见做法是先转成 dict:

def to_dict(user):
    return {"name": user.name}

json.dumps(to_dict(user), ensure_ascii=False)

或者提供 default 函数:

json.dumps(user, default=lambda obj: obj.__dict__)

工程里更建议显式定义转换逻辑,避免把内部字段不小心暴露出去。

六、如何选择

选择建议:

  • 对外接口:JSON;
  • 配置文件:JSON 或 YAML;
  • 跨语言通信:JSON、protobuf、msgpack;
  • Python 内部临时缓存:可以考虑 pickle;
  • 不可信数据:不要用 pickle loads;
  • 长期存储:谨慎 pickle,因为代码变更会影响兼容性。

pickle 能力强,但边界窄;JSON 能力简单,但生态通用。

七、常见误区与追问

易错点:JSON 是数据交换格式,pickle 是 Python 对象序列化机制。面试里一定要把“跨语言”和“安全性”放在第一层区别里讲。

  • 误区:pickle 比 JSON 强,所以优先用 pickle。 pickle 能保存更多 Python 对象信息,但只适合可信 Python 环境;对外接口、配置和跨语言交换应优先 JSON。
  • 追问:为什么不能反序列化不可信 pickle? pickle 加载过程可能执行对象构造和还原逻辑,恶意 payload 有机会触发任意代码执行,风险远高于普通数据解析。
  • 误区:JSON 能直接保存任意 Python 对象。 JSON 只支持有限数据类型,如对象、数组、字符串、数字、布尔和 null;自定义对象需要转成 dict 或提供自定义 encoder。
  • 追问:pickle 的版本兼容有什么问题? pickle 数据依赖 Python 类路径和对象结构,代码重构、类名移动、Python 版本或协议差异都可能导致旧数据无法加载。
  • 误区:序列化后内容一定可读可调试。 JSON 文本可读性较好;pickle 是二进制协议,不适合作为人工编辑或跨系统长期存储格式。
  • 追问:缓存内部 Python 对象时怎么选? 可信、短生命周期、只在 Python 内部使用时可以考虑 pickle;长期存储、跨服务通信或外部输入应选择 JSON、MessagePack、Protobuf 等更明确的格式。

八、加强记忆

JSON 是跨语言文本数据格式,适合传输和配置;pickle 是 Python 专用对象序列化,适合内部临时保存。最重要的红线是:不要反序列化不可信 pickle。面试回答要同时讲格式、兼容性、支持类型和安全性。