← [ BACK_TO_NOTES ]

Python JSON 与序列化

json 模块编解码文本与 Python 基础类型;自定义对象需 default/钩子或显式 DTO。

#concept #growing #dev #python #python

[!info] related notes

Python JSON 与序列化

这个概念为什么出现

API、配置、日志事件普遍 JSON。类型映射与失败模式(非法 JSON、非 UTF-8、不可序列化对象)必须清楚。

[!abstract] 一句话理解 json.dumps 生成 str;loads 接受 str、bytes 或 bytearray,结果也可以是标量或 None。复杂对象需显式转换,语法解析不等于业务校验。

最小可运行示例

场景:下单 API 编解码 body

# order_json_demo.py
# 业务意图:解析下单 JSON 并回编码响应。
# 教学点:loads/dumps;类型映射;错误。

import json


def parse_order(raw: str) -> dict:
    data = json.loads(raw)
    if not isinstance(data, dict):
        raise ValueError("order must be a JSON object")
    if not isinstance(data.get("sku"), str) or not data["sku"].strip():
        raise ValueError("sku must be a nonempty string")
    # bool 是 int 的子类,此处要求真正的正整数。
    if type(data.get("qty")) is not int or data["qty"] <= 0:
        raise ValueError("qty must be a positive integer")
    return data


def main() -> None:
    raw = '{"sku":"SKU-1","qty":2}'
    order = parse_order(raw)
    print(order)
    print(json.dumps({"ok": True, "order": order}, ensure_ascii=False))
    try:
        parse_order("{")
    except json.JSONDecodeError as exc:
        print("bad json:", type(exc).__name__)


if __name__ == "__main__":
    main()

建议运行:

python order_json_demo.py

期望输出:

{'sku': 'SKU-1', 'qty': 2}
{"ok": true, "order": {"sku": "SKU-1", "qty": 2}}
bad json: JSONDecodeError

结合场景再看三个关注点

  1. 对象→dict/list/str/number/bool/null。
  2. datetime/自定义类需转换。
  3. ensure_ascii=False 保留非 ASCII 字符,仍返回 str;写文件/网络时另定编码。本例只检查根对象、sku 和 qty,不验证库存、权限或幂等性。

核心概念与准确模型

JSONPython
objectdict
arraylist
stringstr
numberint/float
true/false/nullTrue/False/None
  • load/dump 针对文件
  • default= / object_hook

边界情况与反直觉行为

  1. 浮点数默认解析为 float;金额需要精确小数时可用 parse_float=Decimal,但 Decimal 再编码需显式策略。
  2. JSON 对象键是字符串;dumps 仅自动转换 str/int/float/bool/None 键,tuple 等键默认报 TypeError。转换可能导致键冲突,往返后也不会恢复原键类型。
  3. 大整数与 JavaScript 互操作时应约定安全范围或字符串表示。
  4. 默认编码/解析允许 NaN、Infinity 等非标准值;编码可设 allow_nan=False,解析可用拒绝常量的 parse_constant。重复对象键默认保留最后一个,需拒绝时使用 object_pairs_hook。

常见误区

[!warning] 常见误区:直接 dumps 任意对象 错误理解:魔法序列化一切。
正确模型:先明确 DTO/编码规则;asdict 的结果仍可能含 datetime、Decimal 等不可直接 JSON 编码的值。

工程实践

  • 边界校验(pydantic 等)
  • 版本化 schema
  • 日志脱敏

本节总结

JSON 是跨服务契约。编解码简单,契约治理不易。

自测题

  1. loads 失败抛什么?
  2. dataclass 怎么 JSON?
参考答案
  1. 非法 JSON 语法通常抛 JSONDecodeError;非法字节编码可抛 UnicodeDecodeError,不支持的输入类型可抛 TypeError,自定义钩子也可抛其他异常。
  2. 先 asdict 或显式 DTO,再按字段类型转换;自定义编码器不等于自动验证 schema。

延伸阅读与资料来源

资料类型支撑内容
json文档标准库
创建于 2026/7/15 更新于 2026/10/6
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本