Python Dataclasses
In this page:
What is a Dataclass?
A dataclass is a class whose main job is holding structured data rather than complex behavior. Adding the @dataclass decorator above a class definition automatically generates __init__, __repr__, and __eq__ for you based on the class's annotated fields, eliminating the boilerplate you'd otherwise hand-write for a simple data container.
Example: What is a Dataclass?
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
p = Point(1, 2)
print(p)
Default Values
Assigning a default value to a field (e.g. count: int = 0) means callers can omit that argument entirely when constructing an instance, and Python fills it in automatically. This works exactly like a normal function's default arguments, since @dataclass builds its __init__ the same way you would by hand.
Example: Default Values
from dataclasses import dataclass
@dataclass
class Counter:
count: int = 0
print(Counter())
print(Counter(5))
Type Hinting in Dataclasses
Every field in a dataclass must carry a type annotation -- it's how the decorator discovers which class attributes are actual data fields versus ordinary class-level code. Beyond that mechanical requirement, the annotations double as documentation, making the shape of your data obvious from the class body alone.
Example: Type Hinting in Dataclasses
from dataclasses import dataclass
@dataclass
class Product:
name: str
price: float
p = Product("Book", 9.99)
print(p)
Read-Only Dataclasses
Passing frozen=True to the decorator makes instances immutable after construction: any attempt to reassign an attribute raises a FrozenInstanceError. This is useful whenever you want value-object semantics, like using instances as dictionary keys or guaranteeing a record can't be silently mutated elsewhere in the codebase.
Example: Read-Only Dataclasses
from dataclasses import dataclass, FrozenInstanceError
@dataclass(frozen=True)
class Point:
x: int
y: int
p = Point(1, 2)
try:
p.x = 5
except FrozenInstanceError:
print("Cannot modify a frozen dataclass")
The field() Function
Using a mutable default like [] or {} directly as a field value is a trap borrowed from ordinary function defaults -- every instance would end up sharing the exact same list object. The field(default_factory=list) pattern fixes this by calling the factory fresh for each new instance instead of reusing one shared object.
Example: The field() Function
from dataclasses import dataclass, field
@dataclass
class Cart:
items: list = field(default_factory=list)
a = Cart()
b = Cart()
a.items.append("apple")
print(a.items, b.items)
Chapter Quiz — Complete all 12 topics to unlock
0/12 topics done
Complete these topics first: