con't define variable in pydantic init function
Question:
i want to define a Base model that inherits from pydantic BaseModel like bellow
class BaseDomain(BaseModel):
def __init__(self, **kwargs):
self.__exceptions = []
def add_error(self, exception: GeneralException):
self.__exceptions.append(exception)
but i get this error when i use Product model that inherits from BaseDomain
ValueError: "Product" object has no field "_BaseDomain__exceptions"
Answers:
Because you have overidden pydantic’s init method that is executed when a class that inherits from BaseModel is created. you should call super()
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.__exceptions = []
EDIT
It seems that pydantic throws that error because it validates __exceptions as an input and throws an error because it isn’t defined in the classes annotations
Try this:
from typing import List, Any
class BaseDomain(BaseModel):
__exceptions:List[Any] = []
def __init__(self, **kwargs):
super().__init__(**kwargs)
Please introduce super in the init method.
def __init__(self,**kwargs):
super().__init
Another version with "underscore_attrs_are_private" option
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())
Use PrivateAttr
with default factory:
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)
Works both with one underscore or two undescores in names.
i want to define a Base model that inherits from pydantic BaseModel like bellow
class BaseDomain(BaseModel):
def __init__(self, **kwargs):
self.__exceptions = []
def add_error(self, exception: GeneralException):
self.__exceptions.append(exception)
but i get this error when i use Product model that inherits from BaseDomain
ValueError: "Product" object has no field "_BaseDomain__exceptions"
Because you have overidden pydantic’s init method that is executed when a class that inherits from BaseModel is created. you should call super()
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.__exceptions = []
EDIT
It seems that pydantic throws that error because it validates __exceptions as an input and throws an error because it isn’t defined in the classes annotations
Try this:
from typing import List, Any
class BaseDomain(BaseModel):
__exceptions:List[Any] = []
def __init__(self, **kwargs):
super().__init__(**kwargs)
Please introduce super in the init method.
def __init__(self,**kwargs):
super().__init
Another version with "underscore_attrs_are_private" option
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())
Use PrivateAttr
with default factory:
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)
Works both with one underscore or two undescores in names.