ProgrammationDéveloppeur Backend

Qu'est-ce que les méthodes magiques (méthodes dunders) en Python, comment sont-elles utilisées et pourquoi les redéfinir dans ses propres classes ? Donnez des exemples de leur utilisation et expliquez les nuances importantes à prendre en compte lors de leur implémentation.

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Les méthodes magiques (ou méthodes dunders – d'après double underscore) sont des méthodes spéciales dont le nom commence et se termine par deux underscores, par exemple, __init__, __str__, __add__. Elles permettent d'intégrer les instances de ses propres classes dans la syntaxe et le comportement de Python : définir la réaction aux opérations arithmétiques, aux comparaisons, à la conversion en chaînes de caractères, au travail avec les protocoles de collections, etc.

Exemple :

class Vector: def __init__(self, x, y): self.x = x self.y = y def __add__(self, other): return Vector(self.x + other.x, self.y + other.y) def __str__(self): return f"Vector({self.x}, {self.y})" v1 = Vector(1, 2) v2 = Vector(3, 4) print(v1 + v2) # Appellera v1.__add__(v2), retournera Vector(4, 6)

Question piège.

Si __eq__ n'est pas implémenté dans sa propre classe, comment les instances seront-elles comparées entre elles avec l'opérateur == ?

Réponse : Par défaut, l'opérateur == compare les objets par identité (adresse en mémoire, de manière similaire à l'opérateur is), sauf si on redéfinit la méthode magique __eq__.

class A: pass print(A() == A()) # False, bien que les objets "semblent identiques"

Exemples d'erreurs réelles dues à une connaissance insuffisante des subtilités du sujet.


Histoire

Dans un projet où il fallait comparer des structures de graphe, la méthode __eq__ n'a pas été implémentée. En conséquence, lors de la vérification "le nœud a-t-il déjà été ajouté", le résultat était incorrect, car l'opérateur == comparait les objets par id, et non par contenu.


Histoire

Lors de l'écriture d'une API REST, l'objet était sérialisé en chaîne pour le journal via str(obj), mais nous avons oublié de définir __str__. En conséquence, un texte illisible <MyObj object at 0x...> était affiché, ce qui a compliqué le diagnostic des problèmes.


Histoire

Dans une bibliothèque pour des calculs mathématiques, seule __add__ a été implémentée, mais nous avons oublié __iadd__ pour l'opérateur +=. En conséquence, l'expression v += w ne fonctionnait pas comme prévu (un nouvel objet était créé, l'ancien n'était pas mis à jour), ce qui a conduit à des fuites de mémoire dans des calculs complexes.