Question 1Quel est l'avantage de remplacer la comparaison de littéral chaîne "paid" par un Enum ?
enum et dataclasses — Constantes nommées et classes de données
Cet article fait partie du Cours de Python, qui vous permet de maîtriser à partir de zéro les compétences nécessaires pour utiliser Python, des bases jusqu'aux sujets avancés.
Remplacer les littéraux chaîne par Enum, numéroter automatiquement avec IntEnum + auto() et trier, générer le code répétitif via @dataclass, et utiliser field(default_factory=list).
Deux modules pour rendre explicite le sens des valeurs. enum te permet de remplacer les littéraux chaîne dispersés dans ton code par des constantes nommées, donc les fautes de frappe surfacent à l'exécution au lieu de passer en silence. dataclasses fournit un moyen de définir une "classe qui ne fait que contenir des données" en une ligne, en éliminant le code répétitif de __init__ / __eq__ / __repr__.
Enum — remplacer les littéraux chaîne par des constantes nommées
Quand des littéraux chaîne comme "paid" / "shipped" sont dispersés dans ton code, les fautes de frappe comme "shippped" passent inaperçues jusqu'à l'exécution, l'autocomplétion n'aide pas, et les refactorisations sont fragiles. Enum résout ça en définissant l'ensemble des constantes comme une classe — les noms que tu définis s'autocomplètent dans ton éditeur, les fautes de frappe lèvent immédiatement AttributeError, l'itération sur tous les membres marche d'office, et tu obtiens une valeur sûre à utiliser comme clé de dict ou étiquette de switch.
# Chaînes de statut dispersées dans le code
if status == "paid":
ship_order(order_id)
elif status == "shippped": # Faute de frappe — devrait être "shipped", mais tu ne le remarqueras qu'à l'exécution
notify_shipped(order_id)
elif status == "cancelled":
refund(order_id)
from enum import Enum
class OrderStatus(Enum):
PENDING = "pending"
PAID = "paid"
SHIPPED = "shipped"
CANCELLED = "cancelled"
# Accès aux membres : chaque membre porte un nom et une valeur
print(OrderStatus.PAID) # OrderStatus.PAID
print(OrderStatus.PAID.name) # 'PAID'
print(OrderStatus.PAID.value) # 'paid'
# Compare avec ==
status = OrderStatus.PAID
if status == OrderStatus.PAID:
print("Paiement reçu")
IntEnum et auto — numérotation automatique et comparaison numérique
IntEnum est un Enum qui hérite de int, donc les membres se comparent et opèrent arithmétiquement comme des entiers. C'est le bon choix pour les constantes où l'ordre numérique compte — priorités, niveaux, rangs. auto() est une fonction qui assigne les valeurs automatiquement à la place de les écrire à la main : aligne des appels auto() et ils deviennent 1, 2, 3, 4... dans l'ordre de définition.
Quand les nombres spécifiques n'importent pas (seul l'ordre compte), auto() est plus sûr parce que ajouter ou retirer des membres n'oblige pas à réécrire les nombres à la main.
1, 2, 3, .... IntEnum se compare avec int, donc Priority.LOW < Priority.HIGH fonctionne — l'ordre numérique encode la priorité.@dataclass — définir une classe contenant des données en une ligne
Écrire une "classe simple avec juste des champs" à la main signifie définir __init__ pour fixer les attributs, __eq__ (la méthode dunder appelée pour les comparaisons ==) pour l'égalité de contenu, __repr__ (la méthode dunder appelée par print et le REPL) pour un affichage lisible, et ainsi de suite — les mêmes motifs répétitifs alignés à chaque fois. Un seul décorateur @dataclass génère tout ça automatiquement à partir de tes déclarations de champs annotés en type.
En d'autres termes, aligner simplement des attributs annotés en type construit toute la classe — tu obtiens les mêmes fonctionnalités pour beaucoup moins de code que les classes écrites à la main.
Utilise default_factory pour les valeurs par défaut mutables
Essayer de mettre une liste par défaut avec @dataclass en écrivant items: list = [] lève une SyntaxError (ou un avertissement de dépréciation). C'est une protection contre le bug classique de "chaque instance finit par partager la même liste". Utilise plutôt field(default_factory=list), qui crée une nouvelle liste vide par instance, ce qui est sûr. Même idée pour dict / set : field(default_factory=dict).
Vérification des connaissances
Répondez à chaque question une par une.
Question 2Quel est l'avantage de auto() dans IntEnum ?
Question 3Quelle est la bonne façon de mettre une liste par défaut sur un champ dans @dataclass ?