JSON 转 Python:转换差异、边界与常见坑

在线 JSON 转 Python:生成带类型标注的 dataclass,并给出 Decimal 与 datetime 所需的解析与序列化钩子,避免浮点与时间在转换中走样。

生成带类型注解的 dataclass,比裸 dict 更容易静态检查。注意标准库 json 不会自动把 dict 变成 dataclass,需要 pydantic 或 dacite;Decimal 与 datetime 也不被标准序列化器认识,要自己写 default 回调。

两种格式的差异对照

维度JSONPython 类型
类型声明无,运行时推断注解可选,运行时不做强制检查
命名camelCase / snake_casePEP 8 推荐 snake_case,需转换或别名
可空性nullOptional[T] 仅作提示,运行时仍需判空
数字统一 numberint 无限精度(大整数天然安全)
浮点numberfloat 双精度,金额用 Decimal
日期字符串需手工转 datetime 并处理时区
不可变无概念frozen dataclass 或 NamedTuple
校验无pydantic 提供运行时校验与类型转换

边界条件

  • int 在 Python 里没有溢出问题,但序列化回 JSON 后若被 JS 解析仍会超过 2^53 失真——Python 侧安全不代表链路安全。
  • float 的 0.1 + 0.2 != 0.3 是二进制浮点的固有问题,金额必须用 Decimal 并配字符串传输。
  • datetime 不带时区(naive)在跨时区比较时会抛异常或产生错误结果,务必用 aware datetime。
  • 可变默认值(如 items: list = [])在 dataclass 里会共享同一个对象,必须用 default_factory。

常见坑

  • 用普通 dict 一路传递,字段拼写错误到运行时才暴露,且难以静态检查。
  • 金额用 float,0.1 + 0.2 的结果让对账差了 5.55e-17。
  • naive datetime 与 aware datetime 混用,线上偶发 TypeError。
  • dataclass 的 list 字段用可变默认值,所有实例共享同一列表,数据互相污染。
  • JSON 的 null 对应 Python 的 None,但类型注解里的 Optional 只在静态检查时生效,运行时仍需判空否则 AttributeError。

相关工具

常见问题

怎么把 Python 再转回 JSON?

使用同工具的交换方向功能,或本站对应的「Python 转 JSON」页面,两者都本地运行、数据不上传,可完成往返转换与校验。

JSON 和 Python 哪个更适合人类阅读?

这取决于场景:Python 通常更偏向程序解析与接口传输式的可读形态,而 JSON 更利于程序解析与接口传输式的程序消费;需要人工编辑时优先选可读性更高的那一侧。

生成的是 dataclass 还是普通 dict?

多数工具生成 @dataclass(带类型注解),可读性与类型提示都更好;但只要 dict 的话直接 json.loads() 就够了。注意:标准库 json 不会自动把 dict 变成 dataclass,需要配 dacite、pydantic 等库,或者手写 from_dict。

datetime 字段会生成什么类型?

通常是 str。因为 JSON 没有日期类型,工具无从判断某个字符串是日期还是普通文本。需要真日期时手工改成 datetime 并在解析层显式转换(datetime.fromisoformat),顺带把时区显式化——这是 Python 里最容易踩的时区坑。