Aller au contenu

Dataclasses#

courant

Motivation#

Génère automatiquement __init__, __repr__, __eq__ pour une classe qui ne fait que porter des données.

from dataclasses import dataclass

@dataclass
class Point:
    x: int
    y: int = 0

p1 = Point(1, 2)
p2 = Point(1, 2)
p1 == p2          # True (__eq__ généré, compare les champs)
print(p1)         # Point(x=1, y=2)  (__repr__ généré)

Équivalent sans dataclass#

class Point:
    def __init__(self, x, y=0):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Point(x={self.x!r}, y={self.y!r})"

    def __eq__(self, autre):
        return (self.x, self.y) == (autre.x, autre.y)

Options courantes#

@dataclass(frozen=True)     # immuable (lève FrozenInstanceError si modifié)
class Coordonnee:
    lat: float
    lon: float

@dataclass(order=True)       # génère __lt__, __le__, __gt__, __ge__
class Version:
    majeur: int
    mineur: int

Valeur par défaut mutable : field#

from dataclasses import dataclass, field

@dataclass
class Panier:
    articles: list[str] = field(default_factory=list)   # jamais list() directement en défaut

Post-initialisation#

@dataclass
class Rectangle:
    largeur: float
    hauteur: float
    aire: float = field(init=False)

    def __post_init__(self):
        self.aire = self.largeur * self.hauteur