如何从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
相关产品推荐
相关产品推荐

