Dataclasses: компактные классы с данными
dataclasses упрощают создание классов‑контейнеров данных: автоматически генерируют __init__, __repr__, __eq__ и другие методы. Меньше шаблонного кода — выше читаемость и меньше шансов на ошибки.
Базовый пример: меньше кода, больше пользы
from dataclasses import dataclass
@dataclass
class Player:
name: str
age: int
team: str
p = Player('Иван', 17, 'Метеор')
print(p) # авто-__repr__
print(p.name, p.age)
q = Player('Иван', 17, 'Метеор')
print(p == q) # авто-__eq__ сравнивает по полям
Player(name='Иван', age=17, team='Метеор')
Иван 17
True
Значения по умолчанию и default_factory
Для изменяемых полей (списки, словари) используйте default_factory, чтобы у каждого экземпляра было своё значение по умолчанию.
from dataclasses import dataclass, field
@dataclass
class Player:
name: str
age: int
team: str
goals: int = 0
history: list[str] = field(default_factory=list)
p1 = Player('Иван', 17, 'Метеор')
p2 = Player('Павел', 18, 'Вымпел')
p1.history.append('Гол в финале')
print(p1.history)
print(p2.history) # независимый список
['Гол в финале']
[]
Неподвижные объекты: frozen=True
Immutability помогает избегать случайных изменений. С frozen=True попытка изменить поле приводит к ошибке.
from dataclasses import dataclass, FrozenInstanceError
@dataclass(frozen=True)
class FrozenPlayer:
name: str
age: int
team: str
fp = FrozenPlayer('Иван', 17, 'Метеор')
print(fp)
try:
fp.age = 18
except FrozenInstanceError as e:
print('Ошибка:', type(e).__name__)
FrozenPlayer(name='Иван', age=17, team='Метеор')
Ошибка: FrozenInstanceError
Мини‑памятка
@dataclassгенерирует__init__,__repr__,__eq__и др. на основе полей.- Для изменяемых значений применяйте
field(default_factory=...)(а не обычный дефолт). frozen=Trueделает экземпляры неизменяемыми (удобно для «значимых» объектов/ключей).- Dataclasses хорошо подходят для «DTO‑подобных» структур, оставляя при этом возможность добавлять методы.