Python 序列化与反序列化指南
1. 序列化概述
程序运行时,所有的变量——无论是简单的字典、列表,还是复杂的自定义类实例——都临时存放在内存堆栈中。一旦程序结束,操作系统会立即回收这些内存,数据也就烟消云散了。
但在实际开发中,我们经常需要“留住数据”:
- 把游戏进度保存成存档,下次接着玩;
- 将爬虫抓取的数据缓存到本地,避免重复请求;
- 在前后端、微服务之间通过 API 传递结构化的信息……
这时,就需要把内存里那些“活的、立体的对象”,转换成可以存储(如写入文件、数据库)或可以传输(如通过网络发送)的格式。这个过程就叫序列化。
(在 Python 的二进制专属工具里,这个过程也被形象地称为 pickling —— 把数据“腌起来”保存。)
反过来,将这些扁平化的数据还原成内存中可以直接操作的对象,就是反序列化(unpickling,解腌)。
接下来,我们就来看看 Python 中最常用的两种序列化方案。
2. Python pickle 模块
pickle 是 Python 自带的最简单、最直接的二进制序列化工具。
它几乎能处理所有 Python 内置类型,甚至连带方法的自定义类实例也不在话下。
2.1 基本用法
核心 API 只有四个,非常好记:
dumps(obj):将对象序列化为bytes类型的二进制串;dump(obj, file):直接序列化并写入文件对象;loads(bytes):从二进制串反序列化回对象;load(file):从文件对象反序列化回对象。
2.2 pickle 的局限性
pickle 虽然方便,但适用场景非常狭窄,主要有三个硬伤:
-
Python 绝对专属
其他语言(Java、Go、JavaScript 等)完全无法理解 pickle 生成的二进制数据,因此它只能用于 Python 环境内部的数据交换。 -
版本兼容性差
不同 Python 大版本(例如 2.x 和 3.x)甚至小版本(如 3.8 和 3.12)之间生成的 pickle 文件很可能不兼容,升级解释器后可能无法正常读取旧存档。 -
高危安全漏洞
千万不要反序列化来自不受信任来源的 pickle 数据!
pickle 的还原过程本质上是在执行一段 Python 字节码,恶意构造的 pickle 文件可以直接运行任意系统命令,从而删除你的重要文件、窃取隐私甚至控制你的电脑。 :::
3. JSON 序列化
JSON(JavaScript Object Notation)是目前最通用的跨语言文本序列化格式。
不仅 Python、JavaScript、Java、Go 等主流语言都原生支持,而且 JSON 本身是纯文本,人类读起来也很清晰。
3.1 数据类型对应表
JSON 是一种“轻量级”格式,只支持六种基本类型。
Python 的标准库 json 在序列化和反序列化时会自动进行类型映射:
3.2 基本用法
json 模块的 API 设计和 pickle 非常相似,核心方法还是四个,但处理的对象是 UTF-8 文本或文本形式的字符串:
3.3 处理好中文字符(一个实用小技巧)
::: tip 中文显示优化
默认情况下,json.dumps 会把非 ASCII 字符(如中文)转义为 \uXXXX 的形式。
对于程序来说前后端都能正常解析,但人类肉眼阅读时非常不友好。
只需加上 ensure_ascii=False,就能保留原生的中文字符。
同时一定要记得在读写文件时显式指定 encoding="utf-8",避免出现乱码。
4. 序列化自定义对象
json 模块默认不能直接处理自定义类的实例,需要我们自己提供“对象 → 字典”的转换逻辑。
常用的方式有两种。
4.1 简单方法:直接使用 __dict__
如果你的类只是一个纯粹的数据容器,没有私有属性,也没有复杂的继承关系,那么可以直接使用 Python 对象自带的 __dict__ 属性——它会自动把实例的所有公开属性打包成一个字典。
4.2 更灵活的方法:实现专属 to_dict 和 from_dict
当你的类存在私有属性、继承自父类的属性,或者希望在序列化时标记类信息方便全局反序列化,更推荐在类内部专门实现转换方法。
5. 安全与最佳实践
不论你选择哪一种序列化方案,都请牢牢记住以下几点:
-
pickle 绝对不要碰不受信任的数据
这一点再强调也不为过。只在自己完全掌控的脚本、本地缓存或内部管道中使用 pickle。 -
对 JSON 输入进行严格的结构校验
反序列化后的数据很可能会缺失字段或出现不期望的类型,你需要手动检查,或者使用pydantic等校验库来保证数据结构的可靠。 -
始终做好exception-handling
无论是文件不存在、权限不足,还是 JSON 格式错误,都可能随时发生。
示例:
6. 性能优化(大数据场景)
当处理的数据量达到 GB 级别,或者在高并发网络请求中频繁使用 JSON 时,标准库 json 可能会成为性能瓶颈。此时不妨考虑以下替代方案。
6.1 更快的 JSON 库
-
orjson
目前 Python 生态中最快的 JSON 库,安装方式:pip install orjson。
它返回的是bytes而不是str,并且可以自动序列化datetime、UUID等常见类型。 -
ujson
速度也比标准库快得多,兼容性略好于orjson,安装方式:pip install ujson。
6.2 二进制跨语言格式
如果对解析速度和数据压缩率有更高要求,可以放弃纯文本的 JSON,转而使用二进制格式:
-
MessagePack
结构与 JSON 类似,但体积更小、速度更快。安装方式:pip install msgpack。 -
Protocol Buffers(protobuf)
谷歌出品的结构化二进制序列化格式,性能最强、压缩率最高,但需要提前编写.proto文件来定义数据结构,上手成本稍高。
7. 总结
选择序列化方案时,请根据你的核心需求做出权衡:
最后再强调一遍:安全第一,pickle 只信自己!

