I have this project where my base class and my sub-classes implement pydantic.BaseModel
:
from pydantic import BaseModel
from typing import List
from dataclasses import dataclass
@dataclass
class User(BaseModel):
id: int
@dataclass
class FavoriteCar(User):
car_names: List[str]
car = FavoriteCar(id=1, car_names=["Acura"])
print(f"{car.id} {car.car_names[0]}")
But this error appears:
self.__fields_set__.add(name)
E AttributeError: __fields_set__
Does someone mind explaining what is going on? The reason why I want to use pydantic is because I need a way to quickly convert Python objects to dict
(or JSON) and back.
If you don't want to use pydantic 's BaseModel you can instead get the same data validation on standard dataclasses (introduced in python 3.7). Dataclasses work in python 3.6 using the dataclasses backport package.
You can use all the standard pydantic field types, and the resulting dataclass will be identical to the one created by the standard library dataclass decorator. The underlying model and its schema can be accessed through __pydantic_model__ .
Pydantic models can be created from arbitrary class instances to support models that map to ORM objects. To do this: The Config property orm_mode must be set to True. The special constructor from_orm must be used to create the model instance.
Also, fields that require a default_factory can be specified by a dataclasses.field. pydantic.dataclasses.dataclass 's arguments are the same as the standard decorator, except one extra keyword argument config which has the same meaning as Config. After v1.2, The Mypy plugin must be installed to type check pydantic dataclasses.
You need to decide whether to inherit from pydantic.BaseModel
, or whether to use the @dataclass
decorator (either from dataclasses
, or from pydantic.dataclasses
).
Either is fine, but you cannot use both, according to the documentation (bold face added by myself):
If you don't want to use pydantic's BaseModel you can instead get the same data validation on standard dataclasses
E AttributeError: __fields_set__
The first part of your question is already answered by Peter T as Document says - "Keep in mind that pydantic.dataclasses.dataclass is a drop-in replacement for dataclasses.dataclass"
The second part is that you wanted to convert them as dict.
The reason why I want to use pydantic is because I need a way to quickly convert Python objects to dict (or JSON) and back
To answer to that part of your question you can use asdict
of dataclass itself source
from dataclasses import dataclass, asdict
from typing import List
@dataclass
class Point:
x: int
y: int
@dataclass
class C:
l: List[Point]
p = Point(10, 20)
assert asdict(p) == {'x': 10, 'y': 20}
c = C([Point(0, 0), Point(10, 4)])
assert asdict(c) == {'l': [{'x': 0, 'y': 0}, {'x': 10, 'y': 4}]}
There is discussion about these module level helper function(.asdict
& .astuple
) that they arent PEP8 compliant (should be as_dict()
and as_tuple()
) however finally they decided to keep consistency with namedtuple._asdict() and attr.asdict(). source
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With