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.
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.
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.
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.
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.
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.
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.
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éthode | Déclenchée par | Usage typique |
|---|---|---|
| __init__ | Classe() | Initialiser les attributs |
| __str__ | print(obj), str(obj) | Affichage lisible |
| __repr__ | repr(obj), shell | Représentation technique |
| __len__ | len(obj) | Taille d'un conteneur |
| __eq__ | obj1 == obj2 | Égalité par contenu |
| __lt__ | obj1 < obj2, sorted() | Tri des objets |
| __add__ | obj1 + obj2 | Opérateur addition |
| __mul__ | obj * n | Opérateur multiplication |
| __getitem__ | obj[clé] | Accès par index/clé |
| __setitem__ | obj[clé] = val | Assignation par index/clé |
| __contains__ | val in obj | Test d'appartenance |
Par carabde | Mis à jour le 21 avril 2026