python解析json常见错误包括:编码不匹配致乱码、keyerror因字段缺失、数字精度丢失、非标准类型无法序列化;应显式指定编码、用get()安全访问、预处理数字、定制default/object_hook处理特殊类型。

Python 解析 JSON 时出错,多数不是语法问题,而是数据结构理解偏差或类型处理疏忽。关键在看清原始 JSON 是对象(dict)还是数组(list),再按 Python 的对应类型安全访问。
JSON 字符串含中文显示乱码或报错
常见于文件读取或网络响应中未指定编码。Python 3 默认用 UTF-8,但若源数据实际是 GBK 或其他编码,直接 json.loads() 会报 UnicodeDecodeError 或解析后中文变问号。
- 读文件时显式指定 encoding:
open("data.json", "r", encoding="utf-8")(推荐统一用 UTF-8 存储 JSON) - 若必须处理 GBK 编码的 JSON 文件,先按 GBK 读取再解码为字符串,再传给
json.loads() - HTTP 响应中注意
response.encoding是否被自动设错,可手动设为response.encoding = response.apparent_encoding或直接用response.content.decode("gbk")
KeyError:访问不存在的字段就崩溃
JSON 数据结构常不固定——比如 API 返回中某个字段可能缺失、为 null,或嵌套层级比预期浅。硬写 data["user"]["profile"]["name"] 极易触发 KeyError 或 TypeError。
- 用
.get()安全取值:data.get("user", {}).get("profile", {}).get("name", "未知") - 对可能为
null(即 Python 的None)的字段,访问前加判断:if data.get("items"): for item in data["items"]: - 复杂嵌套建议封装成工具函数,或用第三方库如
jsonpath-ng或box类库做容错导航
数字精度丢失:整数变浮点、大整数被截断
JSON 标准本身不区分 int/float,所有数字都按 IEEE 754 浮点表示。Python json.loads() 默认将所有数字转为 float 或 int(小整数能精确表示),但遇到超长整数(如 19 位以上 ID)或带小数的高精度数值(如金融金额),可能意外丢失精度。
立即学习“Python免费学习笔记(深入)”;
- 对需要精确整数的场景(如用户 ID、订单号),用
object_hook预处理字符串型数字:json.loads(s, object_hook=lambda d: {k: (int(v) if isinstance(v, str) and v.isdigit() else v) for k, v in d.items()})(需按业务规则调整) - 更稳妥方式:把关键数字字段定义为字符串传输(API 设计层约定),Python 端保持
str类型,后续按需转int或Decimal - 金融计算务必用
decimal.Decimal,避免用 float 解析金额字段
datetime、bytes 等非标准类型无法直接序列化
json.dumps() 只支持基本类型(dict, list, str, int, float, bool, None)。遇到 datetime、bytes、自定义对象会报 TypeError: Object of type ... is not JSON serializable。
- 简单处理:用
default参数定制序列化逻辑,例如:json.dumps(obj, default=str)(把 datetime 转 ISO 字符串,bytes 转 base64 或 decode 结果) - 更规范做法:为每种类型写明确转换,如
default=lambda o: o.isoformat() if isinstance(o, datetime) else getattr(o, '__dict__', str(o)) - 反向解析时,需在
object_hook中识别特定格式字符串并还原为 datetime 等类型
不复杂但容易忽略。多看一眼原始 JSON 结构,少依赖“应该有”,解析就能稳很多。










