如何从JSON解析具有“Type”类型字段的Pydantic模型?

5 浏览
0 Comments

如何从JSON解析具有“Type”类型字段的Pydantic模型?

如何使用pydantic使以下代码工作?\n

from typing import Type
import pydantic
class InputField(pydantic.BaseModel):
    name: str
    type: Type
InputField.parse_raw('{"name": "myfancyfield", "type": "str"}')

\n它会失败并显示如下错误信息:\n

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

\n但是我需要从json中解析,所以无法直接将Type对象传递给`__init__`方法。

0
0 Comments

问题的出现原因是作者想要将一个Pydantic对象/类型转换为另一个Pydantic对象/类型。作者提供了一个示例代码,其中包含了三个Pydantic类型:PyDanticTypeA、PyDanticTypeB和PyDanticTypeC。它们之间存在继承关系,PyDanticTypeB继承自PyDanticTypeA,PyDanticTypeC也继承自PyDanticTypeA,并且PyDanticTypeC还定义了一个名为attribute_d的字段。

在示例代码中,首先创建了一个PyDanticTypeB对象pydantic_type_b,并传入了一些属性值。然后通过PyDanticTypeC.parse_obj()方法,将pydantic_type_b对象解析为PyDanticTypeC对象pydantic_type_c。最后打印出pydantic_type_c的attribute_d属性值,并将其修改为"e",再次打印。

运行代码后,输出结果为:

d

e

问题的解决方法是使用Pydantic的parse_obj()方法将一个Pydantic对象解析为另一个Pydantic对象。在示例代码中,通过parse_obj()方法将PyDanticTypeB对象解析为PyDanticTypeC对象,实现了类型转换。

0
0 Comments

问题的出现原因:

问题是关于如何从JSON中解析一个包含"Type"类型字段的pydantic模型。pydantic是一个用于数据验证和解析的Python库,它允许我们定义具有类型注释的模型类,并可以将其从JSON等格式的数据中解析出来。然而,pydantic默认不支持解析"Type"类型的字段,因此需要自定义验证器来解决这个问题。

解决方法:

解决方法是使用一个带有"pre=True"的自定义验证器,这样可以尝试使用提供的名称查找一个类。下面是一个可行的示例,首先尝试获取一个内置类,如果失败了,则假设该类在全局命名空间中。

from pydantic import BaseModel, validator
class InputField(BaseModel):
    name: str
    type_: type
    ("type_", pre=True)
    
    def parse_cls(cls, value: object) -> type:
        name = str(value)
        try:
            obj = getattr(__builtins__, name)
        except AttributeError:
            try:
                obj = globals()[name]
            except KeyError:
                raise ValueError(f"{value} is not a valid name")
        if not isinstance(obj, type):
            raise TypeError(f"{value} is not a class")
        return obj
class Foo:
    pass
if __name__ == "__main__":
    print(InputField.parse_raw('{"name": "a", "type_": "str"}'))
    print(InputField.parse_raw('{"name": "b", "type_": "Foo"}'))

输出结果:

name='a' type_=
name='b' type_=

如果你还想支持动态导入,也是可能的。可以参考这里的链接(链接1链接2)获得更多指导。

感谢,这看起来是一个可靠的解决方案。我希望能有一种不需要自己编写验证代码的方法,但可能这是能做到的最好的方法了。

0