Python处理JSON时如何保留浮点数末尾零小数位 适配批量递归处理场景
问题根源
Python标准库json.load默认会将JSON中的数字解析为内置float类型,而float是二进制浮点数结构,本身不存储原始字符串里的后缀零信息,加载完成后原始数字的文本格式已经丢失,直接调用json.dump自然会截断末尾零。
可行适配方案
方案1:纯标准库自定义解析/编码逻辑(适配批量递归处理,无需逐字段修改)
核心思路是在全局层面拦截浮点数的解析和编码过程,完整保留原始数字的文本格式,新增字段的逻辑完全不需要改动。
实现步骤:
- 定义一个简单的容器类,存储原始的数字文本,避免被默认浮点数逻辑处理:
import json # 容器类,仅用来存原始数字字符串 class RawNumber: def __init__(self, raw_text): self.raw_text = raw_text # 自定义浮点数解析函数,替代默认的float转换 def preserve_float(raw_string): return RawNumber(raw_string) # 自定义JSON编码器,处理RawNumber的输出 class PreservingEncoder(json.JSONEncoder): def iterencode(self, o, _one_shot=False): # 遇到存了原始格式的数字,直接输出原文本,不加引号(符合JSON数字语法) if isinstance(o, RawNumber): yield o.raw_text return # 其他类型完全走默认编码逻辑 yield from super().iterencode(o, _one_shot) - 替换原有读写JSON的两行代码即可,递归处理上百个文件时不需要修改任何字段遍历、格式化的逻辑:
# 读取原有JSON,传入自定义的parse_float参数保留数字格式 with open("target.json", "r", encoding="utf-8") as f: data = json.load(f, parse_float=preserve_float) # 正常新增字段即可,新增的普通浮点数会走默认编码逻辑 data["alt"] = 3.467878 # 保存时用自定义编码器输出 with open("output.json", "w", encoding="utf-8") as f: json.dump(data, f, cls=PreservingEncoder, indent=2, ensure_ascii=False)
方案优势:
- 对嵌套极深的JSON结构完全兼容,不需要逐字段判断类型、格式化
- 没有第三方依赖,纯标准库实现,部署无额外成本
- 所有原有数字的格式(包括末尾零、科学计数法、自定义小数位)都会1:1保留,完全符合“不改动原有内容”的要求
方案2:使用带格式保留能力的第三方JSON库
如果不想自己实现自定义逻辑,可以使用原生支持格式保留的JSON解析库,比如demjson3,这类库解析时会完整保留所有节点的原始格式(包括数字小数位、空格、注释等),仅在指定位置插入新增字段,不会改动任何原有内容。
使用示例:
# 先安装依赖:pip install demjson3 from demjson3 import JSON # 读取文件,自动保留所有原始格式 json_obj = JSON(filename="target.json") # 直接新增字段,原有内容不受影响 json_obj["alt"] = 3.467878 # 写入文件,原有格式完全不变 json_obj.write_to_file("output.json")
避坑提示
- 不要用正则直接匹配文本里的数字补零,极易误修改字符串值、注释里的数字,批量处理上百个文件时出错风险极高
- 不要统一给所有浮点数补到固定小数位,这种方式会破坏原有内容的真实格式,不符合“不改动原有内容”的需求
内容的提问来源于stack exchange,提问作者Esteban Arellano
相关产品推荐
相关产品推荐

