json快但功能受限,仅支持str、int、float、bool、None、list、dict七种类型,遇datetime等会抛TypeError;实操中可用default参数转ISO字符串,避免深拷贝。

json.dumps/json.loads 为什么快但功能受限
json 是 Python 标准库中序列化速度最快、兼容性最广的模块,但只支持 str、int、float、bool、None、list、dict 这七种类型。遇到 datetime、set、自定义类实例时会直接抛出 TypeError: Object of type ... is not JSON serializable。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 用
default参数配合isinstance手动转datetime为 ISO 字符串(注意时区) - 避免在
default中做深拷贝或递归处理,否则性能断崖下跌 - 生产环境高频小数据(如 API 响应)优先选
json,别为了“看起来高级”换其他模块
pickle.dumps/pickle.loads 的安全与兼容陷阱
pickle 能序列化几乎所有 Python 对象,包括函数、类实例、闭包,但它是 Python 特有协议,跨语言不可读;更关键的是,pickle.loads() 可执行任意代码 —— 任何来自不可信源的 pickle 数据都等同于远程代码执行漏洞。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 永远不在网络传输、用户上传、日志回放等场景用
pickle - 若必须本地持久化(如缓存中间计算结果),限定使用
protocol=4(Python 3.4+ 默认),它比protocol=3小 10–20%,且支持更多内置类型 -
__reduce__方法可被恶意利用,自定义类若需支持pickle,务必检查其返回值是否可控
yaml.safe_dump/yaml.safe_load 为何又慢又重
PyYAML 的 safe_load 看似安全,但实际解析器仍存在历史 CVE(如 CVE-2017-18342),且默认启用复杂解析逻辑(锚点、标签、自动类型推断),导致性能远低于 json。一个 100KB 的纯字典数据,yaml.safe_load 可能比 json.loads 慢 5–8 倍。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 除非明确需要 YAML 特性(如注释、多文档、锚引用),否则别用
yaml做通用序列化 - 禁用自动类型转换:传入
Loader=yaml.CLoader(需编译安装libyaml)和yaml.load(..., Loader=yaml.CSafeLoader) -
配置文件用
yaml,运行时数据交换别碰它
msgpack.packb/msgpack.unpackb 的二进制优势与隐含成本
msgpack 是唯一在性能、体积、跨语言支持上全面优于 json 的选择:相同数据通常小 30–50%,序列化/反序列化快 2–4 倍。但它默认不保留 key 顺序(Python 3.7+ dict 有序,但 msgpack 不保证),且 datetime 需显式开启 datetime=True 参数,否则变成时间戳整数。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 安装时加
ujson和msgpack的 C 扩展:pip install msgpack --no-binary msgpack - 服务间通信、Redis 缓存、日志批量写入等场景,优先测
msgpack+use_bin_type=True - 不要依赖
msgpack.unpackb(data, raw=False)自动转bytes为str,Python 3 下易引发编码歧义
真正影响选型的往往不是“谁最快”,而是“谁在你的数据结构、部署环境、上下游约束下不出错”。比如用 msgpack 存 numpy.ndarray,得额外配 ext_hook;而 json 明知慢,却因浏览器直读、CDN 缓存友好,成了事实标准。选模块前,先跑一遍你的真实数据样本,用 timeit 测三轮,比看任何 benchmark 都管用。











