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. 输入
把内容粘贴或拖入工具面板。
-
2. 处理
点击按钮,在浏览器内本地处理,文件不上传。
-
3. 复制 / 下载
一键复制结果或下载到本地。
JSON 转 Python Dataclass 适合怎么用
适合穿插在写代码、查问题、做 Review、上线前的小任务里。
适合开发场景
- 格式化、校验、压缩或检查和代码相关的文本。
- 把片段整理好再放进文档、工单、提交或交接材料。
- 不切换工具,快速检查一个小 payload。
开发检查项
- 压缩、混淆这类不可逆处理,先对副本操作。
- 除非确认工具本地处理,不要粘贴密钥和敏感片段。
- 转换后的代码上线前,仍要跑自己的测试或 lint。
下一步可以接着做
这些入口会把当前任务接到更完整的工具链里。
- 1 JSON 转 Go 结构体 JSON 转 Go struct, 粘 JSON 出带 json tag 的结构体, 字段自动导出, 嵌套对象生成子 struct, 可空字段用指针, 支持 int64 与 omitempty。 打开
- 2 JSON 转 TypeScript Interface JSON 转 TypeScript interface, 粘 JSON 出干净 interface, 数组元素合并为 union, 可选字段自动识别, 根类型名可命名。 打开
- 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, 让你偏好的风格在多次访问之间保留。
常见问题
类似工具组合
做你这行的人, 还会一起用这些。