Oh MyUtils

JSON转Python - 在线生成数据类和Pydantic模型

将JSON转换为Python dataclass、Pydantic BaseModel或TypedDict,支持类型推断、snake_case转换和日期检测 — 100%浏览器端处理.

根类名
格式
Syntax
选项
JSON输入
Python输出
 

常见问题

什么是JSON转Python转换器?

JSON转Python转换器是一个从JSON数据自动生成Python类定义的工具。无需手动编写带有字段名和类型注解的dataclass或Pydantic模型,只需粘贴一个示例JSON对象,工具就会为每个字段推断正确的Python类型。支持三种输出格式:Python dataclass(标准库)、Pydantic BaseModel(内置验证)和TypedDict(轻量级类型提示)。

如何从JSON生成Python类?

将JSON数据粘贴到左侧的输入字段中。工具会立即在右侧的输出面板中生成Python代码。使用格式选择器选择您喜欢的输出格式(dataclass、Pydantic BaseModel或TypedDict)。您可以通过设置根类名、启用snake_case转换、将null值标记为Optional以及切换日期检测来自定义输出。

应该使用dataclass还是Pydantic BaseModel?

当需要简单的、无依赖的带类型注解的数据容器时,使用Python dataclass。dataclass是标准库的一部分(Python 3.7+),没有运行时验证开销。当需要运行时数据验证、自动类型转换、JSON序列化/反序列化和别名支持时,使用Pydantic BaseModel。TypedDict用于只需要字典类型数据的类型提示而不需要运行时开销的情况。

此工具支持Pydantic v2吗?

是的,此工具专门生成Pydantic v2代码。它使用现代Pydantic v2语法,包括model_config = ConfigDict(...),而不是旧版的class Config模式。启用snake_case转换时,会生成Field(alias='originalKey')和model_config = ConfigDict(populate_by_name=True)。

使用此工具时JSON数据安全吗?

是的,完全安全。此工具使用客户端JavaScript在浏览器中处理所有内容。您的JSON数据永远不会离开您的计算机——没有服务器上传、没有API调用、没有数据存储。这使得它可以安全地用于敏感的API响应、专有数据模式和机密配置文件。

工具如何处理null和可选字段?

当JSON字段有null值时,工具将其标记为Optional并设置默认值为None。对于现代Python语法(3.10+),这变成'field_name: str | None = None'。对于旧版语法,使用'field_name: Optional[str] = None'。您还可以启用'全部可选'切换来将所有字段标记为可选。

嵌套的JSON对象如何处理?

每个嵌套的JSON对象会转换为单独的命名类。例如,如果JSON中有一个包含'address'子对象的'user'对象,工具会创建'User'类和'Address'类,'User'将'Address'作为字段类型引用。类在输出中正确排序,使依赖项出现在引用它们的类之前。

代码示例

// JSON to Python dataclass/Pydantic generator
function jsonToPython(json, rootName = 'Root', format = 'dataclass') {
  const classes = [];

  function toPascalCase(str) {
    return str.replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : '')
              .replace(/^./, s => s.toUpperCase());
  }

  function toSnakeCase(str) {
    return str.replace(/([A-Z])/g, '_$1').replace(/^_/, '').toLowerCase();
  }

  function inferType(value, name) {
    if (value === null) return 'None';
    if (typeof value === 'boolean') return 'bool';
    if (typeof value === 'number') {
      return Number.isInteger(value) ? 'int' : 'float';
    }
    if (typeof value === 'string') return 'str';
    if (Array.isArray(value)) {
      if (value.length === 0) return 'list[Any]';
      return `list[${inferType(value[0], name)}]`;
    }
    if (typeof value === 'object') {
      const className = toPascalCase(name);
      const fields = Object.entries(value).map(([key, val]) => {
        const pyType = inferType(val, key);
        const fieldName = toSnakeCase(key);
        if (format === 'pydantic' && fieldName !== key) {
          return `    ${fieldName}: ${pyType} = Field(alias="${key}")`;
        }
        return `    ${fieldName}: ${pyType}`;
      });

      if (format === 'dataclass') {
        classes.push(`@dataclass\nclass ${className}:\n${fields.join('\n')}`);
      } else if (format === 'pydantic') {
        classes.push(`class ${className}(BaseModel):\n${fields.join('\n')}`);
      } else {
        classes.push(`class ${className}(TypedDict):\n${fields.join('\n')}`);
      }
      return className;
    }
    return 'Any';
  }

  const parsed = JSON.parse(json);
  inferType(parsed, rootName);
  return classes.reverse().join('\n\n');
}

// Example
const json = '{"userName": "alice", "age": 30, "address": {"city": "NYC"}}';
console.log(jsonToPython(json, 'User', 'pydantic'));
// Output:
// class Address(BaseModel):
//     city: str
//
// class User(BaseModel):
//     user_name: str = Field(alias="userName")
//     age: int
//     address: Address

相关工具