无法在Pydantic的init函数中定义变量

3
我想定义一个继承自pydantic BaseModel的基础模型,如下所示:
class BaseDomain(BaseModel):

    def __init__(self, **kwargs):
        self.__exceptions = []

    def add_error(self, exception: GeneralException):
        self.__exceptions.append(exception)


但是当我使用从BaseDomain继承的Product模型时,会出现此错误。
ValueError: "Product" object has no field "_BaseDomain__exceptions"
4个回答

9
由于您重写了继承自BaseModel的类创建时执行的pydantic的init方法,因此您应该调用super()。
def __init__(self, **kwargs):
    super().__init__(**kwargs)
    self.__exceptions = []

编辑

看起来 pydantic 会抛出该错误是因为它将 __exceptions 视为输入进行验证,并因其未在类注释中定义而引发错误

尝试这样做:

from typing import List, Any

class BaseDomain(BaseModel):
    __exceptions:List[Any] = []

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

在类级别上使参数可变是一个错误:https://gist.github.com/deniskrumko/4d4d9a6735f723435222116cc0d7f133 - undefined
1
使用pydantic时不是问题 @deniskrumko - 请参阅https://dev59.com/8VIG5IYBdhLWcg3wmCck#63808835 - undefined

3

使用默认工厂函数和PrivateAttr

https://pydantic-docs.helpmanual.io/usage/models/#private-model-attributes
from pydantic import BaseModel, PrivateAttr

class MyClass(BaseModel):
    normal_value: int
    __private_value__: Dict[str, int] = PrivateAttr(default_factory=dict)
    _private_list: List = PrivateAttr(default_factory=list)

可以使用一个下划线或两个下划线来命名。


0

另一个版本带有"underscore_attrs_are_private"选项

from typing import List, Optional, Any
from pydantic import BaseModel

class BaseDomain(BaseModel):
    __exceptions: Optional[List[Any]] = None
    class Config:
        underscore_attrs_are_private = True

    def add_error(self, exception: Exception):
        if self.__exceptions is None:
            self.__exceptions = []
        self.__exceptions.append(exception)
        
    def get_exceptions(self):
        return self.__exceptions
        
class Item(BaseDomain):
    name: str

item = Item(name="test")
print(item.get_exceptions())
item.add_error(Exception("test"))
print(item.get_exceptions())

-1
请在init方法中介绍一下super关键字。
def __init__(self,**kwargs):
super().__init

1
如果你解释一下为什么需要super调用,这个答案可以更好。你可以使用编辑按钮来提供额外的信息给你的帖子。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接