В чем разница между обычным классом Python, dataclass и Pydantic
Что проверяют
Умеете ли вы выбирать инструмент под задачу и понимаете ли, что валидация бывает нужна не всегда.
Как отвечать
Три уровня одной задачи, «описать структуру данных».
- обычный класс: полный контроль, но
__init__,__repr__,__eq__пишутся руками. Уместен, когда у объекта есть поведение, а не только поля; dataclassиз стандартной библиотеки: декоратор генерирует конструктор, представление и сравнение по полям. Аннотации типов здесь только подсказка, проверок в рантайме нет: передадите строку туда, где объявленint, никто не возразит. Естьfrozen=Trueдля неизменяемости иslots=Trueдля экономии памяти;- Pydantic: модель проверяет и приводит данные при создании. Строка
"42"для поляintстанет числом, неверное значение даст понятную ошибку со списком проблем. Есть сериализация, схемы JSON, собственные проверки полей. Платой идут зависимость и накладные расходы при создании объектов, хотя во второй версии ядро переписано на Rust и это стало заметно быстрее.
Правило выбора простое: данные пришли снаружи (тело запроса, конфигурация, ответ чужого API), берём Pydantic; данные уже свои и проверены, берём dataclass; нужен объект с поведением и своей логикой, берём обычный класс.
Отдельно стоит назвать NamedTuple и TypedDict для случаев, когда нужен просто кортеж или словарь с типами, и attrs как более старую и гибкую альтернативу dataclass.
Где спотыкаются
Считают, что dataclass проверяет типы. Он их только объявляет.
Тащат Pydantic во внутренние структуры и платят проверкой за каждый созданный объект в горячем цикле.
Используют изменяемое значение по умолчанию в dataclass и получают ошибку: для списков и словарей нужен field(default_factory=list).