Ответ
Модуль dataclasses, входящий в стандартную библиотеку Python с версии 3.7, предоставляет декоратор @dataclass для автоматической генерации специальных методов в классах, предназначенных для хранения данных.
Основная цель — сократить количество шаблонного (boilerplate) кода, который разработчикам приходилось писать вручную.
Что генерируется по умолчанию:
__init__(): конструктор для инициализации полей.__repr__(): строковое представление для отладки (например,Point(x=1.5, y=2.5)).__eq__(): метод для сравнения объектов на равенство.
Сравнение "до" и "после":
Без @dataclass:
class Point:
def __init__(self, x: float, y: float):
self.x = x
self.y = y
def __repr__(self):
return f"Point(x={self.x}, y={self.y})"
def __eq__(self, other):
if not isinstance(other, Point):
return NotImplemented
return self.x == other.x and self.y == other.y
С @dataclass:
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
Дополнительные возможности:
- Создание неизменяемых (immutable) объектов с помощью
@dataclass(frozen=True). - Генерация методов сравнения (
__lt__,__gt__и др.) с помощью@dataclass(order=True). - Тонкая настройка полей с помощью функции
field(), например, для исключения поля из__init__или__repr__.
Ответ 18+ 🔞
А, слушай, этот ваш dataclasses модуль в Питоне, который с версии 3.7... Ну, в общем, он тебе жизнь упрощает, блядь. Суть в чём? Есть декоратор @dataclass. Ты его навесил на класс — и он тебе кучу этого шаблонного говна, которое ты вечно пишешь, сам сгенерирует, нахуй.
Зачем это вообще? Чтобы не писать одно и то же, как последний мудак, по сто раз. Руки отваливаются, блядь.
Что он тебе по умолчанию нагенерит, этот волшебник:
__init__()— конструктор, чтобы поля инициализировать. Не надо самомуself.x = xписать.__repr__()— чтоб при отладке объект красиво показывался, типаPoint(x=1.5, y=2.5). А не какая-то хуйня вроде<__main__.Point object at 0x7f8b1c0b5d30>.__eq__()— чтоб сравнивать объекты на равенство. А то самому писатьself.x == other.x and self.y == other.y... Да пошло оно нахуй.
Смотри, как было и как стало. Просто пиздец.
Раньше, без @dataclass, ты бы писал как конченый:
class Point:
def __init__(self, x: float, y: float):
self.x = x
self.y = y
def __repr__(self):
return f"Point(x={self.x}, y={self.y})"
def __eq__(self, other):
if not isinstance(other, Point):
return NotImplemented
return self.x == other.x and self.y == other.y
А теперь, с @dataclass, ты пишешь три строчки и идёшь пить чай:
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
Вот и вся магия, ёпта. Овердохуище времени экономит.
А ещё там прикольные фишки есть, на которые можно глаз положить:
- Неизменяемые объекты — сделай
@dataclass(frozen=True), и всё, объект как вкопанный. Попробуй изменить поле — получишьFrozenInstanceErrorпрямо в ебальник. - Сравнение по порядку —
@dataclass(order=True)тебе автоматом__lt__,__gt__и прочую хуйню нагенерит. Удобно сортировать. - Тонкая настройка полей через
field(). Хочешь поле из__init__выкинуть? Изи. Хочешь, чтоб в__repr__не светилось? Без проблем. Всё решаемо, блядь.
В общем, вещь. Пользуйся, не будь мудаком.