python 是否可以对同一个pydantic basemodel制作不同的版本?

rwqw0loc  于 2023-05-21  发布在  Python
关注(0)|答案(1)|浏览(144)

标题说明:

假设我们有以下pydantic模型的设置:

class ParametersA(BaseModel):
    param_a: str = Field(
        default=...,
        allow_mutation=False,
        exclude=False,
        description="some description.",
        extra={
            "additional_bool": False
        }
    )
    param_b: bool = Field(
        default=False,
        allow_mutation=True,
        exclude=False,
        description="some description.",
        extra={
            "additional_bool": False
        }
    )
    # many more parameters of all types with additional constaints (le, gt, max_items,...)

class ParametersB(BaseModel):
    param_c: float = Field(
        default=-22.0,
        exclude=False,
        allow_mutation=True,
        description="some floaty description",
        gt=-180.0,
        le=0.0,
        extra={
            "additional_bool": False,
            "unit": "degree"
        }
    )
    param_d: List[str] = Field(
        default=["auto"],
        exclude=False, 
        allow_mutation=True,
        min_items=1,
        max_items=4,
        unique_items=True,
        description="Some listy description.",
        extra={
            "auto_mode_available": False
        }
    )
    # many more parameters of all types with additional constaints (le, gt, max_items,...)

这两个模型是另一个BaseModel中的字段:

class FullModelX(BaseModel):
    parameters_A: ParametersA
    parameters_B: ParametersB

问题是,是否有可能创造另一种模式:

class FullModelY(BaseModel):
    parameters_A: ParametersA
    parameters_B: ParametersB

可以重用类ParametersAParametersB,但具有不同的验证限制和不同的元数据?例如,在FullModelX中,ParametersAparam_b的默认值可能是False,而在FullModelX中,它应该是True。这同样适用于任何其他FieldInfo属性,如excludegtle等。
到目前为止,我唯一的解决方案是每次需要一些其他验证约束时复制ParametersAParametersB

zazmityj

zazmityj1#

因此,在大多数情况下,我认为用户@Maxim的回答所建议的继承将是一条可行的道路。
在我的特殊情况下,几乎所有的模型字段都在或其他FieldInfo属性上更改,因此继承实际上意味着重写整个类。
我找到了下面的解决方案,它似乎更适合我的情况。根据我最初更改param_b的示例,FullModelY的代码看起来像这样:

ParametersAVariant= create_model(
    'ParametersAVariant',
    __base__=ParametersA
    )

ParametersAVariant.__fields__['param_b'].default=True

class FullModelY(BaseModel):
    parameters_A: ParametersAVariant
    parameters_B: ParametersB

不确定这是否比简单的代码复制更易读,但至少在大多数情况下,初始模型可以重用。

相关问题