JSON 转 Python Dataclass
即时从 JSON 生成 Python dataclass,支持 @dataclass、Pydantic v2 BaseModel 和 TypedDict,处理嵌套对象、数组、可选字段和自定义根类名。免费,在浏览器中运行。
- 在浏览器中处理
- 数据不离开你的设备
- 免费 · 无需注册
用微信扫描以下二维码即可分享
示例、说明与常见问题 带实际输出的示例、与同类工具的差别,以及常见问题。
类型映射
null→Optional[Any] = None- 字符串 →
str - 整数 →
int - 浮点数 →
float - 布尔值 →
bool - 数组 →
List[T] - 混合数组 →
List[Union[T1, T2]] - 嵌套对象 → 独立类
示例
给定如下 JSON:
{"user": {"first_name": "Alice", "age": 30}, "tags": ["admin"], "note": null}
@dataclass 模式下生成:
from dataclasses import dataclass
from typing import Any, List, Optional
@dataclass
class User:
first_name: str
age: int
@dataclass
class Root:
user: User
tags: List[str]
note: Optional[Any] = None
示例:嵌套对象与缺失的键
输入:
{"id": 7, "title": "Release notes", "author": {"name": "Alice", "email": null}, "tags": ["python", "json"], "score": 4.5, "comments": [{"user": "bob", "text": "nice"}, {"user": "carol"}]}
@dataclass 模式的输出:
from dataclasses import dataclass
from typing import Any, List, Optional
@dataclass
class Author:
name: str
email: Optional[Any] = None
@dataclass
class CommentsItem:
user: str
text: Optional[str] = None
@dataclass
class Root:
id: int
title: str
author: Author
tags: List[str]
score: float
comments: List[CommentsItem]
类的顺序保证每个类在被使用前已定义。第二条评论缺少 text,所以它是 Optional[str] = None。
dataclass、Pydantic 还是 TypedDict
三种模式描述的结构相同,运行时行为不同(Python 3.12、Pydantic 2.13 实测):
root = Root(**json.loads(raw))
type(root.author) # <class 'dict'>, not Author
root = Root.model_validate(json.loads(raw)) # Pydantic mode
root.comments[1] # CommentsItem(user='carol', text=None)
- @dataclass 不校验也不转换。
Root(**data)里的嵌套对象仍是普通 dict,类型不对也照样接受。数据可信时再用,或者自己转换嵌套字段。 - Pydantic 会校验类型并构造嵌套模型,适合处理你控制不了的 API 响应。
model_validate_json(raw)一步完成解析和校验。 - TypedDict 只给类型检查器描述 dict 的结构,运行时什么都不检查。所有键默认都是必需的,工具把只在部分元素里出现的键写成
NotRequired[...](PEP 655,Python 3.11+ 在typing中,更早版本用typing_extensions)。Optional[...]只表示值可以是None,键仍然必需。
示例:带缺失键的 TypedDict
两个商品:note 在第一个里为 null、在第二个里缺失,discount 只出现在第二个里(根类名 Product,TypedDict 模式):
[{"id": 1, "sku": "PEN-01", "price": 2, "note": null}, {"id": 2, "sku": "INK-07", "price": 1.5, "discount": 0.1}]
from typing import Any, NotRequired, Optional, TypedDict
class Product(TypedDict):
id: int
sku: str
price: float
note: NotRequired[Optional[Any]]
discount: NotRequired[float]
price 一个是 2、一个是 1.5,PEP 484 允许 int 当作 float 使用,所以字段是 float。运行时 Product.required_keys 为 {'id', 'sku', 'price'},optional_keys 为 {'note', 'discount'}(Python 3.12 实测)。
限制
null会变成Optional[Any],请把Any换成真实类型。- 不是合法 Python 标识符的键(如
user-id,或class这样的关键字)需要改名,Pydantic 里再配Field(alias="user-id")。 - 日期保持为
str;把类型改成datetime后,Pydantic 会解析 ISO 8601 字符串。 - 根节点是基础类型数组时不生成类。
空数组与样本覆盖
空数组没有提供元素类型的依据,因此 {"tags": []} 会生成 tags: List[Any]。在同一输入数组中加入另一个含 {"tags": ["admin"]} 的对象,合并后的字段就变为 List[str]。生成器依据你提供的样本推断类型,无法推断所有样本中都未出现的字段。复制类定义前,请加入具有缺失键和 null 值的代表性对象。
FAQ
这个工具生成什么?
从 JSON 生成 Python 类定义,可选标准 @dataclass(stdlib)、Pydantic v2 BaseModel 或 TypedDict。每个嵌套对象都会成为独立的命名类。
支持哪些输出模式?
三种模式:@dataclass(Python 标准库,默认)、Pydantic v2 BaseModel、TypedDict(Python 3.8+;用到 NotRequired 时需 3.11+ 或 typing_extensions)。
JSON 类型如何映射到 Python 类型?
string→str、integer→int、float→float、boolean→bool、null→Optional[Any]、array→List[T]、嵌套对象→独立类。
何时字段标记为 Optional?
当 JSON 样本中字段值为 null,或在合并数组对象时某些对象中字段缺失,该字段被标记为 Optional[T] = None。
嵌套对象如何处理?
每个嵌套对象提取为独立类,类名由字段名转换为 PascalCase。子类始终在父类之前定义,输出可直接使用。
我的数据会发送到服务器吗?
不会。整个转换在浏览器中运行,数据不会离开本机。