Python json模块仅支持None、bool、int、float、str、list、tuple、dict(键为str)的原生序列化;set、datetime、bytes、自定义类等会报TypeError;可通过default参数、继承JSONEncoder或预处理数据结构来安全扩展。

Python 的 json 模块不能直接序列化任意对象,它只支持有限的几种原生 Python 类型。所谓“序列化边界”,就是指哪些类型能被 json.dumps() 或 json.dump() 安全处理,哪些会报错,以及如何在边界外安全扩展。
json 原生支持的类型(安全边界内)
以下类型可直接被 json 模块序列化,无需额外处理:
-
None → JSON
null -
bool(
True/False)→ JSONtrue/false -
int、float → 对应 JSON 数字(包括
inf、-inf和nan会被转为null或引发ValueError,取决于allow_nan参数) - str → JSON 字符串(自动处理 Unicode、转义)
- list、tuple、dict(键必须是 str)→ JSON 数组和对象
常见不支持类型及典型错误
以下类型调用 json.dumps() 会直接抛出 TypeError:
-
set:报
Object of type set is not JSON serializable - datetime、date、time:无法自动转字符串
- bytes、bytearray:需先解码为 str 或编码为 base64 字符串
-
自定义类实例(如
class Person: pass):默认无__dict__映射逻辑,也不触发任何转换 - 函数、模块、type、ellipsis (…) 等:完全不在序列化语义范围内
突破边界的常用方法
有三种主流方式在保持 json 标准兼容的前提下扩展序列化能力:
立即学习“Python免费学习笔记(深入)”;
-
使用
default参数:传入一个 callable,当遇到不支持类型时,由它返回一个可序列化的替代值。例如:json.dumps(obj, default=lambda x: x.isoformat() if isinstance(x, datetime) else str(x)) -
继承
json.JSONEncoder:重写default()方法,更清晰、可复用。适合项目中统一处理日期、枚举、自定义模型等。 -
预处理数据结构:在调用
dumps前,用递归或工具函数(如dataclasses.asdict()、pydantic.BaseModel.model_dump())将复杂对象转为 dict/list/str/int/float/None 组合。
特别注意的边界细节
有些行为看似“能过”,实则隐含风险:
-
dict 的 key 必须是 str:若传入
{1: "a", (1,2): "b"},会报错;{'1': "a", '(1, 2)': "b"}才合法 -
浮点精度丢失:JSON 规范不定义浮点精度,Python 默认用
repr()级别输出,但某些极小或极大浮点数可能被科学计数法表示或截断 -
循环引用:
json模块不检测也不支持,会无限递归导致RecursionError -
NaN / Infinity:默认禁止(
ValueError),开启allow_nan=True后会转为null(非标准 JSON),部分解析器可能拒绝










