Почему я получаю AttributeError: __fields_set__ при создании подкласса Pydantic BaseModel?

У меня есть этот проект, в котором мой базовый класс и мои подклассы реализуют 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) и обратно.


person Kendrick Lamar    schedule 10.02.2020    source источник
comment
Я обновил сообщение лучшим примером. Это похоже на код, который у меня есть в моем src.   -  person Kendrick Lamar    schedule 11.02.2020
comment
Похоже, вы можете воспроизвести это без подкласса FavoriteCar, а dataclass и BaseModel каким-то образом конфликтуют.   -  person chepner    schedule 11.02.2020
comment
Раньше я не приводил полный пример. Решил проблему благодаря любой помощи. Вы не можете использовать декоратор @dataclass с pydantic, я не уверен на 100%, почему, но это может быть потому, что pydantic делает что-то особенное с аннотированными данными в фоновом режиме.   -  person Kendrick Lamar    schedule 11.02.2020
comment
Похоже, я пропустил кое-что очень важное: pydantic-docs.helpmanual.io/usage/dataclasses < / а>   -  person Kendrick Lamar    schedule 11.02.2020


Ответы (2)


Вам нужно решить, наследовать ли от pydantic.BaseModel или использовать @dataclass декоратор (либо from dataclasses, либо from pydantic.dataclasses).

Любой из них подходит, но вы не можете использовать оба, согласно документации (добавлен жирный шрифт сам):

Если вы не хотите использовать базовую модель pydantic, вы можете вместо этого получить такую ​​же проверку данных в стандартных классах данных.

person Peter Thomassen    schedule 11.02.2020

E   AttributeError: __fields_set__

На первую часть вашего вопроса Питер Т уже ответил: в документе говорится: "Сохранить" в виду, что pydantic.dataclasses.dataclass - это прямая замена для dataclasses.dataclass

Вторая часть заключается в том, что вы хотели преобразовать их как dict.

Причина, по которой я хочу использовать pydantic, заключается в том, что мне нужен способ быстро преобразовать объекты Python в dict (или JSON) и обратно.

Чтобы ответить на эту часть вашего вопроса, вы можете использовать asdict самого класса данных 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}]}

Обсуждается эта вспомогательная функция на уровне модуля (.asdict & .astuple), что они не совместимы с PEP8 (должны быть as_dict() и as_tuple()), однако, в конце концов, они решили сохранить согласованность с namedtuple._asdict () и attr.asdict (). исходный код

person Shakeel    schedule 12.02.2020