@dataclass
Un décorateur qui génère __init__, __repr__ et __eq__ à partir des champs annotés d’une classe qui sert à stocker des données.
- Renvoie
- La même classe, complétée par les méthodes générées.
Exemple
#from dataclasses import dataclass, field
@dataclass
class Student:
name: str
world: int
points: int = 0
badges: list[str] = field(default_factory=list)
lea = Student("Léa", 7)
lea.points += 40
lea.badges.append("Start")
print(lea)
print(lea == Student("Léa", 7, 40, ["Start"]))
print(Student("Lucas", 2))Définition et utilisation
#Le décorateur @dataclass du module dataclasses supprime le code répétitif des classes qui stockent des données. Il suffit de lister les champs avec leurs annotations de type (name: str) : le décorateur génère un __init__ dont les paramètres suivent le même ordre, un __repr__ lisible et un __eq__ qui compare les objets champ par champ.
Les champs peuvent avoir des valeurs par défaut (points: int = 0), mais ceux qui n’en ont pas doivent venir avant. Pour utiliser une liste, un dictionnaire ou un autre objet modifiable comme valeur par défaut, passez par field(default_factory=list) : chaque objet reçoit alors sa propre copie. Les étapes supplémentaires après la création de l’objet, comme une validation ou le calcul d’un champ auxiliaire, vont dans la méthode __post_init__.
Les paramètres du décorateur modifient le comportement de la classe : frozen=True interdit de modifier les champs, et order=True ajoute les comparaisons < et >. La fonction asdict() transforme l’objet en dictionnaire, par exemple pour l’enregistrer en JSON, et replace() crée une copie avec certains champs modifiés. Les annotations de type ne sont pas vérifiées à l’exécution : elles servent aux éditeurs et à des outils comme mypy.
Syntaxe
#from dataclasses import dataclass, field
@dataclass
class Nom:
champ: type
champ_avec_defaut: type = valeur
liste: list[type] = field(default_factory=list)
@dataclass(frozen=True, order=True)
class Autre:
...Paramètres
#frozen
bool, False par défaut
SiTrue, modifier un champ lèveFrozenInstanceError, et les objets peuvent servir de clés de dictionnaire et d’éléments d’ensemble.order
bool, False par défaut
Ajoute les opérateurs<,<=,>et>=, qui comparent les champs un par un, comme des tuples.slots
bool, False par défaut
Crée la classe avec__slots__: les objets occupent moins de mémoire, et l’affectation à un champ inexistant lève une erreur.kw_only
bool, False par défaut
Impose de passer tous les champs par leur nom lors de la création de l’objet.
Plus d’exemples
#from dataclasses import dataclass, field
@dataclass(frozen=True, order=True)
class Result:
points: int
name: str = field(compare=False)
results = [Result(78, "Lucas"), Result(92, "Léa"), Result(85, "Emma")]
print([r.name for r in sorted(results, reverse=True)])
best = max(results)
try:
best.points = 100
except AttributeError as error:
print(type(error).__name__, error)field(compare=False) exclut le champ des comparaisons : les résultats sont donc triés uniquement selon les points.
from dataclasses import dataclass, field
@dataclass
class Exercise:
number: str
exp: int
world: int = field(init=False)
def __post_init__(self):
if self.exp < 0:
raise ValueError("L'EXP ne peut pas être négatif")
self.world = int(self.number.split("_")[0])
task = Exercise("7_3", 15)
print(task.world)
print(task)import json
from dataclasses import asdict, dataclass, replace
@dataclass
class Course:
title: str
modules: int
premium: bool = False
python = Course("Python", 12)
advanced = replace(python, title="Python avancé", premium=True)
print(advanced)
print(asdict(python))
print(json.dumps(asdict(advanced), ensure_ascii=False))Bonnes pratiques
#- Créez les champs à valeur par défaut modifiable avec
field(default_factory=list). L’écriturebadges: list = []lève uneValueErrordès la définition de la classe. - Les types des annotations ne sont pas vérifiés :
Student(name=123, world="sept")crée donc un objet sans erreur. Pour valider, utilisez__post_init__ou la bibliothèque pydantic. - Les objets avec
frozen=Truese partagent sans risque entre les parties d’un programme, car personne ne peut les modifier par accident.
Entrées associées
#- namedtuple vs dataclassnamedtuple crée un tuple léger et immuable à champs nommés ; @dataclass crée une classe ordinaire et modifiable avec __init__, __repr__ et __eq__ générés.
- __init__()Une méthode appelée automatiquement lors de la création d’un objet. Elle y enregistre les données initiales, c’est-à-dire les attributs.
- __str__() et __repr__()Des méthodes qui définissent l’apparence textuelle d’un objet : lisible pour l’utilisateur (__str__) et technique pour le programmeur (__repr__).
- Méthodes spécialesDes méthodes à double underscore qui permettent aux objets de fonctionner avec les opérateurs ==, <, +, in et avec la fonction len().
Vous voyez une erreur ou il manque un exemple ? Écrivez-nous.