logo oujood
🔍

Les méthodes spéciales Python (dunder methods)

Les méthodes spéciales permettent à vos classes de se comporter comme les types natifs Python. Ce cours explique les plus utiles avec des exemples concrets.

OUJOOD.COM

Quand vous écrivez len(ma_liste), Python appelle en réalité ma_liste.__len__(). Quand vous faites a + b, Python appelle a.__add__(b). Ces méthodes encadrées de doubles underscores — qu'on appelle dunder methods (de double underscore) ou méthodes spéciales — sont le mécanisme qui permet à vos propres classes de s'intégrer naturellement dans la syntaxe Python.

Définir __len__ dans votre classe, c'est rendre len() utilisable dessus. Définir __add__, c'est permettre l'opérateur +. Ce cours présente les méthodes spéciales les plus utiles avec des exemples concrets.

__init__ : le constructeur

__init__ est appelée automatiquement à la création d'un objet. C'est ici qu'on initialise les attributs de l'instance. Elle ne retourne rien — son rôle est uniquement de préparer l'objet.

  📋 Copier le code

class Livre:
    def __init__(self, titre, auteur, pages):
        self.titre = titre
        self.auteur = auteur
        self.pages = pages

livre = Livre("Le Petit Prince", "Saint-Exupéry", 96)
print(livre.titre)
# Résultat : Le Petit Prince

__str__ et __repr__ : représentation textuelle

__str__ définit ce qu'affiche print(objet) — une représentation lisible pour un humain. __repr__ définit la représentation technique, affichée dans le shell interactif ou avec repr(objet). Si __str__ n'est pas défini, Python utilise __repr__ à la place.

  📋 Copier le code

class Livre:
    def __init__(self, titre, auteur, pages):
        self.titre = titre
        self.auteur = auteur
        self.pages = pages

    def __str__(self):
        # Lisible pour l'utilisateur
        return f"{self.titre} de {self.auteur} ({self.pages} pages)"

    def __repr__(self):
        # Représentation technique pour les développeurs
        return f"Livre(titre={self.titre!r}, auteur={self.auteur!r}, pages={self.pages})"

livre = Livre("1984", "Orwell", 328)

print(str(livre))
# Résultat : 1984 de Orwell (328 pages)

print(repr(livre))
# Résultat : Livre(titre='1984', auteur='Orwell', pages=328)

__len__ : rendre len() utilisable

__len__ permet d'appeler len() sur vos objets. Elle doit retourner un entier positif ou nul.

  📋 Copier le code

class Bibliotheque:
    def __init__(self):
        self.livres = []

    def ajouter(self, livre):
        self.livres.append(livre)

    def __len__(self):
        return len(self.livres)

biblio = Bibliotheque()
biblio.ajouter("1984")
biblio.ajouter("Le Petit Prince")
biblio.ajouter("Dune")

print(len(biblio))
# Résultat : 3

__eq__ et __lt__ : comparaisons

__eq__ définit le comportement de l'opérateur ==. Sans lui, Python compare l'identité des objets (leur adresse mémoire), pas leur contenu. __lt__ définit <, et une fois défini, sorted() peut trier vos objets.

  📋 Copier le code

class Produit:
    def __init__(self, nom, prix):
        self.nom = nom
        self.prix = prix

    def __eq__(self, autre):
        # Deux produits sont égaux si même nom et même prix
        return self.nom == autre.nom and self.prix == autre.prix

    def __lt__(self, autre):
        # Comparer par prix pour le tri
        return self.prix < autre.prix

    def __str__(self):
        return f"{self.nom} ({self.prix}€)"

p1 = Produit("Clavier", 49)
p2 = Produit("Souris", 29)
p3 = Produit("Clavier", 49)

print(p1 == p3)
# Résultat : True (même nom et même prix)

print(p1 == p2)
# Résultat : False

produits = [p1, p2, Produit("Écran", 199)]
for p in sorted(produits):
    print(p)
# Résultat (triés par prix) :
# Souris (29€)
# Clavier (49€)
# Écran (199€)

__add__ et __mul__ : opérateurs arithmétiques

Ces méthodes permettent d'utiliser les opérateurs +, -, * avec vos objets. Python appelle __add__ quand il rencontre a + b.

  📋 Copier le code

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

    def __add__(self, autre):
        return Vecteur(self.x + autre.x, self.y + autre.y)

    def __mul__(self, scalaire):
        return Vecteur(self.x * scalaire, self.y * scalaire)

    def __str__(self):
        return f"Vecteur({self.x}, {self.y})"

v1 = Vecteur(1, 2)
v2 = Vecteur(3, 4)

print(v1 + v2)
# Résultat : Vecteur(4, 6)

print(v1 * 3)
# Résultat : Vecteur(3, 6)

__getitem__ et __setitem__ : accès par index

__getitem__ permet d'utiliser la notation objet[index]. __setitem__ permet objet[index] = valeur. C'est ce qui rend vos objets accessibles comme des listes ou des dictionnaires.

  📋 Copier le code

class Panier:
    def __init__(self):
        self._articles = {}

    def __setitem__(self, article, quantite):
        self._articles[article] = quantite

    def __getitem__(self, article):
        return self._articles.get(article, 0)

    def __str__(self):
        return str(self._articles)

panier = Panier()
panier["pommes"] = 3
panier["poires"] = 2

print(panier["pommes"])
# Résultat : 3

print(panier["cerises"])
# Résultat : 0 (absent, valeur par défaut)

__contains__ : l'opérateur in

__contains__ définit le comportement de l'opérateur in. Sans lui, Python parcourt l'objet avec __iter__ si disponible.

  📋 Copier le code

class ListeNoire:
    def __init__(self):
        self._interdits = set()

    def ajouter(self, element):
        self._interdits.add(element)

    def __contains__(self, element):
        return element in self._interdits

    def __len__(self):
        return len(self._interdits)

liste = ListeNoire()
liste.ajouter("spam@exemple.com")
liste.ajouter("bot@fake.net")

print("spam@exemple.com" in liste)
# Résultat : True

print("alice@exemple.com" in liste)
# Résultat : False

Récapitulatif des méthodes spéciales essentielles

MéthodeDéclenchée parUsage typique
__init__Classe()Initialiser les attributs
__str__print(obj), str(obj)Affichage lisible
__repr__repr(obj), shellReprésentation technique
__len__len(obj)Taille d'un conteneur
__eq__obj1 == obj2Égalité par contenu
__lt__obj1 < obj2, sorted()Tri des objets
__add__obj1 + obj2Opérateur addition
__mul__obj * nOpérateur multiplication
__getitem__obj[clé]Accès par index/clé
__setitem__obj[clé] = valAssignation par index/clé
__contains__val in objTest d'appartenance

Par carabde | Mis à jour le 21 avril 2026