15. Dataclasses
dataclasses are a modern way to define classes that mostly store data. They reduce boilerplate for common tasks such as creating an __init__() method, a readable __repr__(), and value-based equality checks.
15.1. Basic dataclass
Without a dataclass, a simple record type can require a lot of repetitive code.
With @dataclass, Python generates that boilerplate for you.
1from dataclasses import dataclass
2
3
4@dataclass
5class Student:
6 name: str
7 grade: int
8
9
10student = Student('Jane', 11)
11print(student)
15.2. Default values
You can give dataclass fields default values just as you would with function arguments.
1from dataclasses import dataclass
2
3
4@dataclass
5class ServerConfig:
6 host: str = 'localhost'
7 port: int = 8000
8 debug: bool = False
9
10
11config = ServerConfig(debug=True)
12print(config)
15.3. Mutable defaults
Be careful with mutable defaults such as lists and dictionaries. Just like function defaults, they should not be shared across instances accidentally. Use field(default_factory=...) instead.
1from dataclasses import dataclass, field
2
3
4@dataclass
5class ShoppingCart:
6 owner: str
7 items: list[str] = field(default_factory=list)
8
9
10cart = ShoppingCart('John')
11cart.items.append('apples')
12print(cart)
15.4. Frozen dataclasses
If you want instances to behave like immutable records, use frozen=True.
1from dataclasses import dataclass
2
3
4@dataclass(frozen=True)
5class Point:
6 x: int
7 y: int
8
9
10point = Point(2, 3)
11print(point)
15.5. Why dataclasses matter
Dataclasses are especially useful when a class mainly represents structured data rather than complicated behavior. They keep examples short, make code easier to read, and encourage you to model data with named fields instead of anonymous dictionaries or tuples.
15.6. Exercise
Model a small library system with dataclasses. Create a Book dataclass with title, author, year, and tags. Then:
give
tagsa safe default withfield(default_factory=list)create at least three books
compare two books for equality
print the books so you can see the generated
__repr__()