← Back to Python Course | Chapter 11: Advanced Python | Lesson 9 of 12

Python Dataclasses

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?

python
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

python
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

python
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

python
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

python
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)

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.