Hashtagueule

Repérage dans les dataclasses Python

Bonjour !

Aujourd'hui un tout petit tutoriel pour parler esthétique et sémantique dans le développement Python.

Comme vous le savez sûrement, Python a introduit dans sa version 3.7 le nouveau module dataclasses qui permet de réduire la verbosité dans la création de classes. Pour rappel, cela permet de transformer quelque chose comme ça :

class Chat:
    def __init__(self,
                 taille: float = None,
                 âge: int = None, # oui oui, c'est légal, déclarez π = math.pi aussi
                 couleur: str = None,
                 vivant: bool = None, # Schrödinger
                ):
        self.taille = taille
        self.âge = âge
        self.couleur = couleur
        self.vivant = vivant

en ça :

@dataclasses.dataclass
class Chat:
    taille: float
    âge: int
    couleur: str
    vivant: bool

avec éventuellement plein de paramètres dans le décorateur dataclass, que je vous encourage à aller lire dans la doc Python. On devine assez facilement ce que font les options :

- init=True
- repr=True
- eq=True
- order=False
- unsafe\_hash=False
- frozen=False

et les conséquences de leurs valeurs par défaut, mais il y a quelques subtilités qui mérite un peu de lecture.

Ce sur quoi je souhaitais mettre l'accent dans cet article, c'est l'existence de la méthode __post_init__ dans le module. En effet, cette méthode est très pratique, et je trouve qu'elle permet facilement de distinguer deux types d'usages de dataclass.

En général, les classes qui n'utilisent pas cet méthode sont plus souvent des vraies dataclass, au sens classes qui contiennent de la données, comparable à une struct en C ou au Records java à venir.

A contrario, celles qui utilisent cette méthode peuvent parfois être des classes qui retiennent un état, par exemple pour de la configuration, mais celles-ci peuvent faire des choses bien plus avancées dans cette méthode qui est appelée automatiquement après la méthode init qui, je le rappelle, est gérée par le module dataclasses.

Par conséquent, si vous rencontrez une dataclass, cela peut être pour deux raisons :

  • utiliser une nouvelle fonctionalité Python déclarative et plus élégante ;
  • créer un objet contenant principalement de la donnée.

Connaître cette distinction sémantique et l'avoir en tête permet une analyse statique du code à la lecture plus rapide, je suis tombé sur une occurrence de ce phénomène et la partage donc.

Joyeux code !

Motius