pydantic.BaseModel:父类的类方法

Posted

技术标签:

【中文标题】pydantic.BaseModel:父类的类方法【英文标题】:pydantic.BaseModel: classmethod of a parent 【发布时间】:2021-09-08 14:51:14 【问题描述】:

如何调用父类的类方法?

我需要将 ORM-model 导入 Pydantic 模型。我知道有一个pydantic.BaseModel.from_orm,但在我的情况下它不会起作用,因为我有必须手动转换的字段。例如,我有一个 phone_number 字段,它本身不能表示为str。这就是为什么我要写“my-own-another-one-from-orm-method”。

让我们忘记 ORM。我已经画了一个我希望工作的例子:

>>> class Parent(BaseModel):
...     a: int
...     @classmethod
...     def import_(cls, a: int) -> "Parent":
...         new = cls(a=a)
...         return new
>>> class Child(Parent):
...     b: int
...     @classmethod
...     def import_(cls, a: int, b: int) -> "Child":
...         new = cls(b=b, **super().import_(a).dict())
...         return new
>>> Child.import_(a=1, b=2)

不幸的是,它失败了。据我了解一个错误,super() 出于某种原因从Child 调用import_。好吧,也许我没有正确理解错误,但是有:

pydantic.error_wrappers.ValidationError: 1 validation error for Child
b
  field required (type=value_error.missing)

1 validation error for Child
b
  field required (type=value_error.missing)

我应该写什么来让这个例子正确存在?

【问题讨论】:

【参考方案1】:

为了做你想做的事,你需要显式地使用基类名称来调用它的Parent.import_(a) 方法,因为当使用super() 时,cls 将被设置为子类(实际对象类型)。

class Child(Parent):
    b: int

    @classmethod
    def import_(cls, a: int, b: int) -> "Child":
        parent = Parent.import_(a).dict()
        new = cls(b=b, **parent)
        return new

【讨论】:

以上是关于pydantic.BaseModel:父类的类方法的主要内容,如果未能解决你的问题,请参考以下文章

在 pydantic 模型中包含非验证方法是不好的做法吗?

为啥在子类化 Pydantic BaseModel 时会出现“AttributeError:__fields_set__”?

Typescript中的类

一种专门用来作父类的类——抽象类

python的类的super()

Pickle 动态生成具有灵活父类的类?