Глава 14 · Создаём объекты реального мира
dataclasses
Классы, которые в основном хранят данные, не обязаны писать __init__ и __repr__ вручную.
Меньше шаблонного кода для классов-данных
Классы вроде Tochka из раздела 14.22 — в основном
шаблонный код: __init__, который просто копирует параметры в
self, плюс __str__ и
__eq__, которые почти всегда выглядят одинаково. Модуль
dataclasses умеет сгенерировать всё это автоматически:
Класс-данные: вручную и через @dataclass
Обычный класс
class Tochka:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"Tochka(x={self.x}, y={self.y})"
def __eq__(self, other):
return self.x == other.x and self.y == other.y
С @dataclass
from dataclasses import dataclass
@dataclass
class Tochka:
x: int
y: int
# __init__, __repr__ и __eq__ сгенерированы автоматически
Что использовать сегодня: @dataclass — там, где класс в основном ХРАНИТ данные и не выигрывает от ручного контроля над __init__/__repr__/__eq__. Он всё ещё обычный класс — методы добавляются в тело точно так же, как и всегда.
dataclass_s_metodom.py
from dataclasses import dataclass
@dataclass
class Tochka:
x: int
y: int
def rasstoyanie_do(self, other):
return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5
a = Tochka(0, 0)
b = Tochka(3, 4)
print(a) # Tochka(x=0, y=0) — __repr__ уже готов
print(a.rasstoyanie_do(b)) # 5.0
Частое заблуждение: «dataclass — это не настоящий класс» или «в dataclass нельзя писать методы»
Оба неверны.
@dataclass — это обычный декоратор класса: он лишь ДОБАВЛЯЕТ автосгенерированные __init__, __repr__, __eq__ поверх обычного тела класса. Методы, property и вообще всё, что можно писать в обычном классе, точно так же пишется и в dataclass.Debug Lab 13: изменяемое значение по умолчанию в dataclass
izmenyaemoe_polei_umolchanie.py
from dataclasses import dataclass
@dataclass
class Korzina:
tovary: list = [] # похоже на ловушку из раздела 14.8!
Traceback (most recent call last):
ValueError: mutable default for field tovary is not allowed: use default_factory
Python dataclasses УМЫШЛЕННО запрещает изменяемое значение по умолчанию прямо в аннотации — это тот же самый риск общего списка на все объекты, что и в разделе 14.8, только для dataclass он обнаруживается сразу, ошибкой при определении класса, а не тихим багом во время выполнения.
Исправленный код
s_default_factory.py
from dataclasses import dataclass, field
@dataclass
class Korzina:
tovary: list = field(default_factory=list) # новый список для КАЖДОГО объекта
Практика: dataclasses
Интерактивный ноутбук прямо в браузере — Python 3.14 через Pyodide, без установки