21

我有这个项目,我的基类和子类在其中实现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]}")

但是出现了这个错误:

    self.__fields_set__.add(name)
E   AttributeError: __fields_set__

有人介意解释发生了什么吗?我想使用 pydantic 的原因是因为我需要一种快速将 Python 对象转换为dict(或 JSON)并返回的方法。

4

2 回答 2

12

您需要决定是继承自pydantic.BaseModel,还是使用@dataclass装饰器(或者from dataclasses,或from pydantic.dataclasses)。

根据文档(我自己添加的粗体),两者都可以,但您不能同时使用两者:

如果您不想使用 pydantic 的 BaseModel,您可以改为在标准数据类上获得相同的数据验证

于 2020-02-11T02:41:57.157 回答
1
E   AttributeError: __fields_set__

正如Document所说,Peter T 已经回答了您问题的第一部分- “请记住,pydantic.dataclasses.dataclass 是 dataclasses.dataclass 的替代品”

第二部分是您想将它们转换为 dict。

我想使用 pydantic 的原因是因为我需要一种方法来快速将 Python 对象转换为 dict(或 JSON)并返回

要回答您问题的那一部分,您可以使用asdict数据类本身的

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}]}

有关于这些模块级辅助函数(.asdict& .astuple)的讨论,它们不符合 PEP8(应该是as_dict()and as_tuple()),但最终他们决定与 namedtuple._asdict() 和 attr.asdict() 保持一致。资源

于 2020-02-12T10:27:19.837 回答