PythonMastery

Dataclass in Python

Use @dataclass to get __init__, __repr__ and __eq__ written for you. Includes default values, field(default_factory=list) and sorting objects.

A class that mostly holds data needs the same three methods every time: __init__, __repr__ and __eq__. The @dataclass decorator writes them for you from the list of fields.

The program

python
from dataclasses import dataclass, field


@dataclass
class Employee:
    name: str
    salary: float
    skills: list[str] = field(default_factory=list)
    remote: bool = False

    def add_skill(self, skill):
        self.skills.append(skill)


ada = Employee("Ada", 75000, ["Python", "SQL"])
alan = Employee("Alan", 82000, remote=True)
alan.add_skill("Maths")

print(ada)
print(alan)
print(ada == Employee("Ada", 75000, ["Python", "SQL"]))
output
Employee(name='Ada', salary=75000, skills=['Python', 'SQL'], remote=False)
Employee(name='Alan', salary=82000, skills=['Maths'], remote=True)
True

How it works

Sorting and frozen objects

order=True adds <, > and the others, comparing the fields in order. frozen=True makes the objects read-only:

python
from dataclasses import dataclass


@dataclass(order=True, frozen=True)
class Version:
    major: int
    minor: int
    patch: int


versions = [Version(3, 12, 1), Version(3, 9, 18), Version(3, 13, 0)]
print(max(versions))
print(sorted(versions)[0])

try:
    versions[0].major = 4
except AttributeError as e:
    print("Error:", type(e).__name__)
output
Version(major=3, minor=13, patch=0)
Version(major=3, minor=9, patch=18)
Error: FrozenInstanceError

FrozenInstanceError is a kind of AttributeError, so except AttributeError catches it. Frozen objects can be used as dictionary keys and in sets.

Learn the idea: Dataclasses, Object-Oriented Programming

A longer explanation: Use a dataclass for records, not a dict