Dataclasses Competent¶
Basic usage¶
Basic usage in Dataclasses — what it is and when to use it.
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
p = Point(3.0, 4.0)
print(p) # Point(x=3.0, y=4.0) — auto __repr__
print(p == Point(3.0, 4.0)) # True — auto __eq__
Default values & fields¶
Default values & fields in Dataclasses — what it is and when to use it.
from dataclasses import dataclass, field
@dataclass
class Config:
host: str = "localhost"
port: int = 8080
tags: list = field(default_factory=list) # mutable default
Frozen (immutable)¶
Frozen (immutable) in Dataclasses — what it is and when to use it.
@dataclass(frozen=True)
class Coordinate:
lat: float
lon: float
c = Coordinate(40.7, -74.0)
c.lat = 0 # FrozenInstanceError!
Post-init processing¶
Post-init processing in Dataclasses — what it is and when to use it.
@dataclass
class Circle:
radius: float
area: float = field(init=False)
def __post_init__(self):
self.area = 3.14159 * self.radius ** 2
Ordering & comparison¶
Ordering & comparison in Dataclasses — what it is and when to use it.
order=True generates __lt__, __le__, etc., comparing fields as a tuple:
from dataclasses import dataclass
@dataclass(order=True)
class Version:
major: int
minor: int
print(Version(1, 2) < Version(1, 5)) # True
print(sorted([Version(2, 0), Version(1, 9)]))
# [Version(major=1, minor=9), Version(major=2, minor=0)]
slots=True — smaller, faster instances¶
slots=True — smaller, faster instances, part of Dataclasses.
Python 3.10+ can generate __slots__, which drops the per-instance __dict__:
from dataclasses import dataclass
@dataclass(slots=True)
class Point:
x: int
y: int
p = Point(1, 2)
print(hasattr(p, "__dict__")) # False — attributes live in slots
Excluding a field from compare / repr¶
Excluding a field from compare / repr in Dataclasses — what it is and when to use it.
from dataclasses import dataclass, field
@dataclass
class User:
name: str
password: str = field(repr=False, compare=False)
u = User("alice", "secret")
print(u) # User(name='alice') — password hidden from repr
print(u == User("alice", "different")) # True — password ignored in ==
Convert to dict / tuple¶
Convert to dict / tuple in Dataclasses — what it is and when to use it.
from dataclasses import dataclass, asdict, astuple
@dataclass
class Point:
x: int
y: int
p = Point(3, 4)
print(asdict(p)) # {'x': 3, 'y': 4}
print(astuple(p)) # (3, 4)
Post-init validation (runnable)¶
Post-init validation (runnable) in Dataclasses — what it is and when to use it.
from dataclasses import dataclass, field
@dataclass
class Circle:
radius: float
area: float = field(init=False)
def __post_init__(self):
if self.radius < 0:
raise ValueError("radius must be non-negative")
self.area = 3.14159 * self.radius ** 2
c = Circle(2)
print(round(c.area, 2)) # 12.57
Practice exercises¶
- Convert a regular class with
__init__,__repr__,__eq__into a@dataclass. - Create a frozen
Colordataclass with RGB values and a computed hex property. - Build a
@dataclasswith validation in__post_init__. - Use
order=Trueto make aCarddataclass sortable by rank then suit. - Use
asdictto serialize a nested dataclass to JSON.
💬 Discussion
Have a question about this topic? Found an error? Share your thoughts below.