当我继承Pydantic BaseModel时,为什么会出现“AttributeError: __fields_set__”错误?

37

我有这个项目,在我的基类和子类中实现了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)并反向转换的方法。


我更新了帖子,并提供了一个更好的例子。这与我src中的代码类似。 - Kendrick Lamar
1
看起来你可以在不使用子类FavoriteCar的情况下重现这个问题,而且dataclassBaseModel之间存在某种冲突。 - chepner
之前我没有提供完整的示例。感谢大家的帮助,我解决了这个问题。在pydantic中,您不能使用@dataclass装饰器。我不确定原因是什么,但可能是因为pydantic在后台对注释数据进行了特殊处理。 - Kendrick Lamar
似乎我忽略了非常重要的事情:https://pydantic-docs.helpmanual.io/usage/dataclasses/ - Kendrick Lamar
2个回答

34
你需要决定是否继承自pydantic.BaseModel,或者使用@dataclass装饰器(可以是from dataclassesfrom pydantic.dataclasses)。

两种方法都可以,但是根据文档(我加粗了一下),你不能同时使用两种方法:

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


1
谢谢!我已经从数据类转换为BaseModel,但忘记了装饰器。 - four43

1
E   AttributeError: __fields_set__

你的问题的第一部分已经被Peter T回答了,文档中说:“请记住,pydantic.dataclasses.dataclass是dataclasses.dataclass的替代品”。
第二部分是你想把它们转换为字典。

我想使用pydantic的原因是我需要一种快速将Python对象转换为字典(或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()as_tuple()。然而最终决定保持与namedtuple._asdict()和attr.asdict()的一致性。source

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