简体   繁体   English

如何从 json 中解析带有“Type”类型字段的 pydantic 模型?

[英]How to parse a pydantic model with a field of type "Type" from json?

How to make the following work with pydantic?如何使用 pydantic 进行以下工作?

from typing import Type

import pydantic


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

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

It fails with它失败了

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

But I need to parse this from json, so I don't have the option to directly pass the Type object to the __init__ method.但是我需要从 json 中解析它,所以我没有直接将 Type 对象传递给__init__方法的选项。

A custom validator with pre=True will allow you to attempt to find a class with the provided name.带有pre=True的自定义验证器将允许您尝试查找具有提供的名称的类。 Here is a working example first trying to grab a built-in and failing that assuming the class is in global namespace:这是一个工作示例,首先尝试获取一个内置的并失败,假设该类位于全局命名空间中:

from pydantic import BaseModel, validator


class InputField(BaseModel):
    name: str
    type_: type

    @validator("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"}'))

Output:输出:

name='a' type_=<class 'str'>
name='b' type_=<class '__main__.Foo'>

If you want to support dynamic imports as well, that is possible too.如果你也想支持动态导入,那也是可能的。 See here or here for pointers.请参阅此处此处以获取指示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM