You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从JSON解析含Type类型字段的Pydantic模型?

如何让这段Pydantic代码正常运行?

原代码如下:

from typing import Type

import pydantic


class InputField(pydantic.BaseModel):
    name: str
    type: Type

InputField.parse_raw('{"name": "myfancyfield", "type": "str"}')

运行时抛出错误:

pydantic.error_wrappers.ValidationError: 1 validation error for InputField
type
  a class is expected (type=type_error.class)

注:由于需要从JSON解析,无法直接向__init__传入Type对象。


解决方案

问题核心是JSON里传的是字符串"str",但Pydantic的Type类型要求必须是类对象(比如直接传str本身),所以得把字符串转成对应的类型对象才行,下面给两种实用方法:

方法一:自定义字段类型(兼容Pydantic v1和v2)

自己实现字段的验证逻辑,完成字符串到Python类型的映射:

from typing import Type, Any
import pydantic

class TypeFromString(pydantic.BaseModel):
    @classmethod
    def __get_validators__(cls):
        yield cls.validate

    @classmethod
    def validate(cls, v: Any, *args, **kwargs) -> Type:
        # 兼容直接传入类型对象的场景
        if isinstance(v, type):
            return v
        # 定义字符串到类型的映射表,按需扩展
        type_map = {
            "str": str,
            "int": int,
            "float": float,
            "bool": bool
            # 可添加自定义类映射:"MyCustomClass": MyCustomClass
        }
        if v not in type_map:
            raise ValueError(f"不支持的类型字符串:{v}")
        return type_map[v]

class InputField(pydantic.BaseModel):
    name: str
    type: TypeFromString

# 测试解析
result = InputField.parse_raw('{"name": "myfancyfield", "type": "str"}')
print(result.type)  # 输出 <class 'str'>

方法二:用Pydantic v2的前置验证器(更简洁)

如果使用Pydantic v2版本,用BeforeValidator装饰器可以更高效实现:

from typing import Type
from pydantic import BaseModel, BeforeValidator

def str_to_type(v) -> Type:
    type_map = {
        "str": str,
        "int": int,
        "float": float,
        "bool": bool
    }
    if isinstance(v, str):
        if v not in type_map:
            raise ValueError(f"不支持的类型:{v}")
        return type_map[v]
    # 非字符串直接返回(兼容直接传类型对象的情况)
    return v

class InputField(BaseModel):
    name: str
    type: Type = BeforeValidator(str_to_type)

# 测试
result = InputField.parse_raw('{"name": "myfancyfield", "type": "str"}')
print(result.type)  # 输出 <class 'str'>

注意事项

  • 可根据业务需求扩展type_map,添加更多内置类型或自定义类
  • 如果需要处理list[str]这类泛型类型,需要在转换逻辑中额外解析字符串格式,实现对应的类型转换

内容的提问来源于stack exchange,提问作者Chr1s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 02:10:32