py
Датаклассы
Зачем нужно?
Для удобной работы с данными / классами
Для сравнения классов по значениям полей, а не по ссылкам
Для валидации полей классов
Для сериализации классов в json и другие примитивы
Для иммутабельности - неизменности полей и хеширования (использование в сетах и словарях)
Пример
import dataclasses
@dataclasses.dataclass()
class FlatRentAd:
link: str
phone: str
address: str
metro: str
price: int
meters: int
floor: int
has_dishwasher: bool
has_conditioner: bool
Как без датаклассов?
class FlatRentAd:
def __init__(
self,
link: str,
address: str,
metro: str,
price: int,
meters: int,
floor: int,
has_dishwasher: bool,
has_conditioner: bool,
phone: str,
):
self.link = link
self.address = address
self.metro = metro
self.price = price
self.meters = meters
self.floor = floor
self.has_dishwasher = has_dishwasher
self.has_conditioner = has_conditioner
self.phone = phone
Без датаклассов, мы написали класс, который умеет только сеттить поля, и он уже занимает в 2 раза больше места
А в датаклассах помимо более компактной записи, мы получаем пачку фич
Напр. сравнение по значению - доступно из коробки, а для обычного класса нужно реализовать метод __eq__
:
class FlatRentAd:
def __init__(
self,
link: str,
address: str,
metro: str,
price: int,
meters: int,
floor: int,
has_dishwasher: bool,
has_conditioner: bool,
phone: str,
):
self.link = link
self.address = address
self.metro = metro
self.price = price
self.meters = meters
self.floor = floor
self.has_dishwasher = has_dishwasher
self.has_conditioner = has_conditioner
self.phone = phone
def __eq__(self, other):
return (
self.link == other.link and
self.address == other.address and
self.metro == other.metro and
self.price == other.price and
self.meters == other.meters and
self.floor == other.floor and
self.has_dishwasher == other.has_dishwasher and
self.has_conditioner == other.has_conditioner and
self.phone == other.phone
)
Метод __eq__
, помимо того что он занимает много места, нужно обновлять каждый раз при добавлении новых полей
А у датаклассов фич много, реализовывать каждую из них в обычном классе - смысла мало
Виды датаклассов
dataclasses - встроено в Python 3.7+
pydantic - улучшенные датаклассы: есть возможность парсить из json, различные
валидаторы, возможность генерировать swagger и многое другое (требуется Python 3.6+)
attrs - еще одна альтернатива стандартным датаклассам, есть поддержка старых
версий Python (Python 2, Python < 3.6)
есть парсилка из json - cattrs