dataclasses
Overview
The `@dataclass` decorator in Python automatically generates boilerplate code for classes that primarily store data. When you add it to a class with type-hinted attributes, it automatically writes the `__init__()`, `__repr__()`, and `__eq__()` methods for you behind the scenes. The mental model is a 'code generator': the decorator inspects the class at definition time, looks at the type hints, and injects the standard dunder methods into the class dictionary as if you had typed them yourself.
It eliminates the repetitive and error-prone work of writing `def __init__(self, x): self.x = x` for every data object.
Where used: Defining ORM models, Config structures, Returning structured data from functions
Why learn this
- You can define a class with 5 attributes in 6 lines of code instead of 20.
- Your classes automatically get a readable string representation and value-based equality comparison.
Code walkthrough
from dataclasses import dataclass
@dataclass
class Product:
name: str
price: float
item = Product('Apple', 1.5)
print(item)
Focus: @dataclass
Aha moment
class NormalClass:
def __init__(self, name: str):
self.name = name
n1 = NormalClass('Bob')
n2 = NormalClass('Bob')
print(n1 == n2)
Prediction: Do two standard classes with identical attributes equal each other?
Common guess: True, because they have the same data.
It prints False. By default, custom classes use identity (memory address) for equality. Dataclasses fix this by automatically generating an __eq__ method for value equality.
Common mistakes
- Forgetting type hints: The `@dataclass` decorator only recognizes fields that have type annotations. A plain assignment like `x = 5` in the class body will be completely ignored by the dataclass generator.
- Default mutable arguments: If you assign a mutable default like `items: list = []`, all instances will share the same list. Dataclasses protect against this by raising a ValueError, but it catches beginners off guard.
Glossary
- type hints
- Annotations in Python code that indicate what type of data (like an integer or string) a variable should hold, e.g. `age: int`.
- boilerplate
- Standard pieces of code that have to be written repeatedly with little to no alteration, e.g. `def __init__(self, x): self.x = x`.
Recall questions
- Which three dunder methods does `@dataclass` automatically generate by default?
- How does the dataclass decorator know which attributes to include in the generated methods?
Understanding checks
What does this code print?
Point(x=5)
The attribute 'y' has no type hint, so @dataclass ignores it. It only generates an __init__ and __repr__ for the annotated 'x' field.
What does this code print?
True
The @dataclass decorator automatically generates an __eq__ method that compares the instances' attributes. Since both have name='Alice', they evaluate as equal.
Practice tasks
Convert to dataclass
Convert this standard class into a dataclass to remove the boilerplate `__init__` and `__repr__` methods.
Challenge
Dataclass with Defaults
Create a dataclass `Server` with a `host` (str) and a `port` (int). Set the default value of `port` to 80.
Continue learning
Previous: __str__ vs __repr__