Dataclasses: Model Data Fast
intermediate13 min readLesson 64 of 169
@dataclass generates __init__, __repr__, and __eq__ so you model, not boilerplate.
Most classes are mostly data. Writing __init__, __repr__, and
__eq__ by hand for each one is boilerplate with bug surface. @dataclass
generates all three from your field declarations:
from dataclasses import dataclass, field
@dataclass
class Task:
title: str
priority: int = 1
tags: list = field(default_factory=list) # safe mutable default
task = Task("ship release", 2)
task == Task("ship release", 2) # True โ __eq__ compares fields
repr(task) # Task(title='ship release', ...)
Three details professionals know:
- Mutable defaults need
field(default_factory=list)โ a baretags=[]would share one list across all instances (same trap asdef f(x=[])). frozen=Truemakes instances immutable and hashable โ great for value objects likeMoneyorPoint.__post_init__runs after__init__for cross-field validation.
When to use which
Plain class โ behavior-heavy objects with complex lifecycle. Dataclass โ data records: rows, configs, messages, DTOs. Reaching for a dataclass first is a signal you're thinking about data shape, which usually makes better designs than thinking about inheritance hierarchies.