Difficulty: Intermediate
What are Python dataclasses? How do they compare to regular classes and namedtuples?
@dataclass (Python 3.7+) automatically generates __init__, __repr__, __eq__, and optionally __lt__, __hash__ based on class attributes.
Advantages over regular class: - No boilerplate __init__ with self.x = x - Auto-generated __repr__ and __eq__ - Clean, declarative syntax with type annotations
Key parameters: - frozen=True: makes instances immutable (generates __hash__) - order=True: generates __lt__, __le__, __gt__, __ge__ - slots=True (3.10+): generates __slots__ for memory efficiency - eq=False: skip __eq__ generation
field() for defaults: use field(default_factory=list) for mutable defaults.
from dataclasses import dataclass, field
from typing import List
@dataclass
class Point:
x: float
y: float
label: str = 'origin'
p1 = Point(1.0, 2.0)
p2 = Point(1.0, 2.0)
print(p1) # Point(x=1.0, y=2.0, label='origin')
print(p1 == p2) # True (auto __eq__)
# Mutable defaults must use field()
@dataclass
class Student:
name: str
grades: List[float] = field(default_factory=list)
_id: int = field(default=0, repr=False, compare=False)
def average(self):
return sum(self.grades) / len(self.grades) if self.grades else 0
s = Student('Alice')
s.grades.extend([85, 90, 95])
print(s) # Student(name='Alice', grades=[85, 90, 95])
print(s.average()) # 90.0
field(default_factory=list) is required for mutable defaults. repr=False and compare=False exclude _id from __repr__ and __eq__.
from dataclasses import dataclass
from math import sqrt
@dataclass(frozen=True, order=True)
class Version:
major: int
minor: int
patch: int
def __str__(self):
return f'{self.major}.{self.minor}.{self.patch}'
v1 = Version(1, 2, 3)
v2 = Version(2, 0, 0)
try:
v1.major = 99 # Raises FrozenInstanceError
except Exception as e:
print(e)
print(v1 < v2) # True (order=True)
print(sorted([v2, v1])) # [Version(1,2,3), Version(2,0,0)]
# __post_init__ for derived fields
@dataclass
class Circle:
radius: float
area: float = field(init=False)
def __post_init__(self):
self.area = 3.14159 * self.radius 2
c = Circle(5)
print(c.area) # 78.53975
frozen=True makes instances hashable and usable as dict keys or in sets. __post_init__ computes derived fields after __init__ runs.
@dataclass, field(), frozen, post_init, slots