跳到主要内容

JSON 转 Python Dataclass 与 Pydantic — 类型注解、Optional、零上传

JSON 转 Python, 粘 JSON 出 @dataclass 或 Pydantic v2 模型, 带类型注解, Optional 推断, 嵌套子类, 字段转 snake_case 并保留别名。

  • 本地处理
  • 分类 开发运维
  • 适合 格式化、校验、压缩或检查和代码相关的文本。
示例:
类型、Optional 和别名是怎么推断的

每个 JSON 对象生成一个命名类 —— 一个 @dataclass 或一个 Pydantic v2 BaseModel。整数推断成 int; 带小数的推断成 float; 一个数字有时是整数有时带小数, 字段会放宽到 float。对象数组会折叠成一个类 —— 某些元素缺的 key (或值为 null) 会变成 Optional[X] = None。只出现过 null 的值推断成 Any。不是合法 Python 标识符的 key 会转成 snake_case, 原始 key 通过 metadata (dataclass) 或 Field(alias=...) (Pydantic) 保留, 这样 (反)序列化能往返。叶子类排在父类之前输出, 文件从上到下导入, 不需要任何前向引用。

这个工具能做什么

把任意 JSON (REST API 响应、webhook body、`config.json`、测试 fixture) 粘进来, 拿到一组带完整类型注解的 Python 类, 可以直接拖进 `.py` 文件。 一个开关在普通 `@dataclass` 和 Pydantic v2 `BaseModel` 之间切换。 类型是推断出来的, 不是一锅端: 整数样本是 `int`, 带小数的是 `float`, 一个字段在某个样本里是整数、在另一个里带小数时会放宽到 `float`, 这样模型不会拒掉一行合法数据。`true`/`false` 是 `bool`, 字符串是 `str`, 只出现过 `null` 的值是 `Optional[Any]`。对象数组会折叠成一个 类, 所以 `[{"a":1},{"a":1,"b":2}]` 出来是一个同时带两个字段的模型, `b` 因为第一个元素里没有被标成 `Optional[int] = None`, 而不是两个 几乎重复、要你手动对齐的类。嵌套对象会抽成各自的命名类 (`User.address` → `UserAddress`), 叶子类排在前面输出, 文件从上到下读、每个引用都不需要 前向声明。不是合法 Python 标识符的 key 会清洗成 `snake_case` —— `userId` → `user_id`, `is-active` → `is_active`, `2fa` → `field_2fa`, `class` → `class_` —— 原始 key 用 Pydantic 的 `Field(alias=...)` 或 dataclass 的 `field(metadata=...)` 保留, 让 (反)序列化往返不丢真实 key。字段排序遵守 Python 规则 (有默认值的字段不能排在无默认值字段 前面), 可变默认值用 `field(default_factory=list)` 绕开那个经典的共享 可变对象 bug。根类名可改, 输入能拼成链接分享, 输出一键复制或下载 `.py`。全部在浏览器里跑 —— JSON 不碰服务器。

工具细节

输入
文件 + 文本 + 数值
页面会根据工具类型展示文本框、数值控件、文件选择或结构化输入。
输出
即时结果 + 复制 + 下载
结果区优先给出可操作结果,支持项会显示复制、下载或可视化预览。
隐私
浏览器本地处理
主工具逻辑未发现外部 API 调用,输入通常留在当前标签页内处理。
保存 / 分享
可分享链接状态
关键设置会进入 URL,复制链接后别人能复现同一组参数。
性能预算
首屏 JS ≤ 25 KB
没有声明 WASM 依赖,适合快速打开和移动端使用。
适用场景
开发运维 · 程序员
分类和职业标签用于推荐相关工具、组织内链,并帮助用户快速判断是否适合当前任务。

怎么用

  1. 1. 输入

    把内容粘贴或拖入工具面板。

  2. 2. 处理

    点击按钮,在浏览器内本地处理,文件不上传。

  3. 3. 复制 / 下载

    一键复制结果或下载到本地。

JSON 转 Python Dataclass 适合怎么用

适合穿插在写代码、查问题、做 Review、上线前的小任务里。

适合开发场景

  • 格式化、校验、压缩或检查和代码相关的文本。
  • 把片段整理好再放进文档、工单、提交或交接材料。
  • 不切换工具,快速检查一个小 payload。

开发检查项

  • 压缩、混淆这类不可逆处理,先对副本操作。
  • 除非确认工具本地处理,不要粘贴密钥和敏感片段。
  • 转换后的代码上线前,仍要跑自己的测试或 lint。

下一步可以接着做

这些入口会把当前任务接到更完整的工具链里。

  1. 1 JSON 转 Go 结构体 JSON 转 Go struct, 粘 JSON 出带 json tag 的结构体, 字段自动导出, 嵌套对象生成子 struct, 可空字段用指针, 支持 int64 与 omitempty。 打开
  2. 2 JSON 转 TypeScript Interface JSON 转 TypeScript interface, 粘 JSON 出干净 interface, 数组元素合并为 union, 可选字段自动识别, 根类型名可命名。 打开
  3. 3 JSON 转 PHP 数组 JSON 转 PHP 数组, 粘 JSON 出干净的关联或索引数组, 支持短语法 [] 与 array(), 2/4 缩进, 末尾逗号, 可选 <?php return …; 包裹。 打开

真实使用场景

  • 接第三方 API 时不再手写类

    你在接一个 REST API, user 对象有 30 多个字段。curl 一次拿到响应, 粘进来, 根名设为 `GitHubUser`, 选 Pydantic v2, 复制输出到 `app/clients/github.py`。嵌套的 `plan` 对象自动抽成 `GitHubUserPlan`, `html_url` 带上别名, 现在 `GitHubUser.model_validate(resp.json())` 给你一个有编辑器自动补全 的类型化对象, 而不是一个靠字符串索引、只能祈祷的原始 `dict`。

  • 给 FastAPI endpoint 生成请求 / 响应模型

    同事发来他在做的 `/orders` POST 的一个 JSON body 样例。粘进来, 根名 `CreateOrderRequest`, 选 Pydantic v2, FastAPI 就会自动校验 body。响应样例也粘进来命名 `CreateOrderResponse`。把两个都放进 `schemas.py`, 接到路由签名上, FastAPI 的 OpenAPI 文档和 422 校验 就白送了 —— 在你们任何一方写 handler 之前。

  • 给可空的 webhook payload 决定用 Optional 还是必需

    某第三方的 webhook 有时带 `cancelled_at`, 有时不带。把前几次 payload 记下来, 作为 JSON 数组粘进来, Optional 识别会把 `cancelled_at` 标成 `Optional[str] = None`。在 handler 里 `if event.cancelled_at is not None:` 就能干净地区分"已取消"和 "仍有效" —— 而真正必需的字段缺了, Pydantic 会直接报错, 不会等到 三层调用之后才抛 `KeyError`。

  • 把 dict[str, Any] 替换成真正的模型

    老代码是 `data: dict = resp.json()`, 然后用 `data["user"]["profile"]["id"]` 一层层挖, 一旦某个 key 改名就在 运行时炸。抓一个有代表性的响应粘进来, 生成 dataclass 或模型, 替换掉 dict。坑过你的字符串索引变成属性访问 (`data.user.profile.id`), mypy / Pyright 在编辑时就抓出拼写错误, 而不是等到生产环境。

  • 给 Python 服务做类型化配置和 fixture

    你的服务读一个 `config.json`。粘进来, 根名 `Config`, 保持 `@dataclass` 做零依赖加载。拿到 `Config`、`ConfigServer`、 `ConfigServerTLS` 嵌套类, 端口是 `int`, 开关是 `bool`, list 字段 已经用上 `field(default_factory=list)`。用 `Config(**json.load(f))` 加载, 一个拼错的 key 在构造时就以清晰的 `TypeError` 失败, 而不是悄悄穿过一个 dict。

常见踩坑

  • 粘一个对象进来然后期待某些字段是 Optional。单个对象没有"key 缺失"信号, 所以所有字段都是必需 (不带 `= None`)。Optional 推断只在"多个对象组成的数组"里 (有的元素带某个 key、有的不带), 或值字面就是 `null` 时生效。想从一个样本探索可选性, 把它包成 `[{...}]`。

  • 忘了 dataclass 在运行时不校验类型。`@dataclass` 只做注解; `User(id="not-an-int")` 照样能构造, 错误的类型就溜过去了。如果 JSON 跨越信任边界 (外部 API、用户输入), 选 Pydantic v2, `model_validate` 才会真正强制并拒掉坏数据。dataclass 是给你已经信任的数据用的。

  • 以为生成的别名不配 populate_by_name 也能用。对 Pydantic, `Field(alias="userId")` 意味着 `model_validate({"userId": 7})` 能用, 但按 Python 名构造 —— `Account(user_id=7)` —— 会报错, 除非你设 `model_config = ConfigDict(populate_by_name=True)`。如果你在代码里造实例 (不只是解析 JSON), 加上这个配置, 或者用别名构造。

  • JSON 里有时带小数却把字段类型手动改成 int。如果一个样本是 `1`、另一个是 `1.5`, 字段会正确放宽到 `float`。手动改窄回 `int` 会让 Pydantic 拒掉 `1.5` 那一行 (或者 dataclass 在 int 注解下存了个 float, 骗过类型检查器)。相信放宽 —— JSON 的 `1` 在 Python 里本来就是合法的 `float`。

  • 粘 JSON5 / 带注释的 JSON / 末尾逗号。我们用严格的 `JSON.parse`, 注释、不带引号的 key、末尾逗号都会带着行 / 列报错。先剥掉, 或者先过一道 JSON 格式化工具。

隐私说明

你粘进来的 JSON 不会离开这个浏览器标签页。解析和类型推断走浏览器 内建的 `JSON.parse`, 没有任何网络请求, 也不对文本框内容做 analytics。 分享链接会把你的输入和根类名编码进 URL 以便复现结果 —— 也就是说由你 决定何时分享。如果 payload 敏感 (内部 ID、客户数据、生产响应), 直接复制生成的 Python 代码, 不要分享链接。只有选项选择 (dataclass 还是 Pydantic、Optional 处理、future import) 会存进 localStorage, 让你偏好的风格在多次访问之间保留。

常见问题

类似工具组合

做你这行的人, 还会一起用这些。

Made by Toolora · 100% client-side · Updated 2026-05-29