json.JSONDecoder 如何自定义处理 NaN / Infinity / -Infinity
发布时间 - 2026-01-25 00:00:00 点击率:次JSONDecoder默认不支持NaN和Infinity,因JSON标准禁止这些值;可通过object_hook或parse_float(需strict=False)实现兼容解析,但编码时仍需自定义处理。
JSONDecoder 默认不支持 NaN 和 Infinity
Python 的 json.JSONDecoder 在解析时遇到 NaN、Infinity 或 -Infinity 会直接报错:ValueError: Invalid value encountered: NaN(或类似提示)。这不是 bug,而是 JSON 标准本身禁止这些值 —— 它们不属于 RFC 7159 合法的 JSON 数字。
但实际中,不少后端(尤其是 JavaScript 环境)会输出带这些值的“类 JSON”字符串。若你必须接收并解析这类输入,就得绕过标准校验。
用 object_hook + float() 强转是最简方案
核心思路:在解析完每个对象(dict)后,遍历其所有字符串值,对匹配 "NaN"、"Infinity"、"-Infinity" 的项尝试用 float() 转换。Python 的 float() 原生支持这些字面量。
示例实现:
import jsondef handle_nan_inf(obj): for key, value in obj.items(): if isinstance(value, str): if value in ("NaN", "Infinity", "-Infinity"): obj[key] = float(value) return obj
data = '{"x": "NaN", "y": "Infinity", "z": 42}' result = json.loads(data, object_hook=handle_nan_inf)
result == {'x': nan, 'y': inf, 'z': 42}
- 仅作用于 dict 层级,不会递归处理嵌套 list 中的字符串;如需全覆盖,改用
object_hook+ 深度遍历,或换用parse_float - 注意
float("NaN")返回的是float('nan'),它不等于自身(nan == nan为False),后续判断要用math.isnan() - 此方式不改变原始 JSON 字符串结构,只在解析后做一次修正,开销小
用 parse_float 捕获所有数字字面量(含非法格式)
parse_float 参数会在 JSON 解析器遇到任何数字 token 时调用,包括那些本该失败的 NaN 字符串 —— 只要它们没被预校验拦住。关键在于:**必须配合 strict=False**,否则解析器在 tokenize 阶段就抛错了。
示例:
import jsondef robust_float(s): try: return float(s) except ValueError:
可选:记录未知格式,或返回 None/0
return float('nan')data = '{"a": NaN, "b": Infinity}' result = json.loads(data, parse_float=robust_float, strict=False)
result == {'a': nan, 'b': inf}
-
strict=False是前提,否则parse_float根本不会被触发 -
parse_float接收的是原始 token 字符串(如"NaN"),不是已解析的数字,所以能捕获非法字面量 - 它对所有数字位置生效(dict 值、list 元素、嵌套任意深度),比
object_hook更彻底 - 副作用:也会处理合法数字字符串(如
"123"),若你的robust_float有额外逻辑,需先判断是否为特殊字面量
别忽略 JSONEncoder 的反向兼容问题
能解析 NaN 不代表能原样输出。Python 的 json.JSONEncoder 默认拒绝编码 float('nan'),会报 ValueError: Out of range float values are not JSON compliant。
- 若需导出,必须自定义
default或继承JSONEncoder,例如:default=lambda x: None if math.isnan(x) else x - 更常见做法是提前清洗数据:入库/传输前把
nan/inf替换为None或特定哨兵值(如"__NaN__"),避免序列化阶段出问题 - 前后端约定比强行兼容更可靠 —— 比如统一用
null表示缺失,用字符串"inf"表示无穷大
真正麻烦的从来不是怎么读进来,而是读进来之后,要不要、以及能不能再安全地写出去。

# javascript
# python
# java
# js
# json
# 编码
# 后端
# red
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel怎么发送邮件_Laravel Mail类SMTP配置教程
如何用低价快速搭建高质量网站?
Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面
Android滚轮选择时间控件使用详解
晋江文学城电脑版官网 晋江文学城网页版直接进入
php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】
如何选择PHP开源工具快速搭建网站?
Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】
深圳网站制作平台,深圳市做网站好的公司有哪些?
企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?
javascript基本数据类型及类型检测常用方法小结
CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】
Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程
Android自定义listview布局实现上拉加载下拉刷新功能
使用Dockerfile构建java web环境
Laravel如何保护应用免受CSRF攻击?(原理和示例)
香港服务器部署网站为何提示未备案?
phpredis提高消息队列的实时性方法(推荐)
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
如何在阿里云ECS服务器部署织梦CMS网站?
Swift中switch语句区间和元组模式匹配
JavaScript模板引擎Template.js使用详解
音乐网站服务器如何优化API响应速度?
JS碰撞运动实现方法详解
Android中AutoCompleteTextView自动提示
Laravel如何实现本地化和多语言支持_Laravel多语言配置与翻译文件管理
如何在万网主机上快速搭建网站?
香港服务器WordPress建站指南:SEO优化与高效部署策略
EditPlus 正则表达式 实战(3)
Laravel怎么实现模型属性转换Casting_Laravel自动将JSON字段转为数组【技巧】
宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法
零基础网站服务器架设实战:轻量应用与域名解析配置指南
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
做企业网站制作流程,企业网站制作基本流程有哪些?
专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?
Angular 表单中正确绑定输入值以确保提交与验证正常工作
简单实现Android验证码
教你用AI润色文章,让你的文字表达更专业
Laravel的.env文件有什么用_Laravel环境变量配置与管理详解
Laravel如何使用Telescope进行调试?(安装和使用教程)
Laravel如何使用Vite进行前端资源打包?(配置示例)
Laravel定时任务怎么设置_Laravel Crontab调度器配置
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
如何用狗爹虚拟主机快速搭建网站?
Laravel如何实现邮箱地址验证功能_Laravel邮件验证流程与配置
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
Microsoft Edge如何解决网页加载问题 Edge浏览器加载问题修复
绝密ChatGPT指令:手把手教你生成HR无法拒绝的求职信
北京的网站制作公司有哪些,哪个视频网站最好?
javascript日期怎么处理_如何格式化输出

