Méthodes spéciales utiles¶
Jusqu’ici, nos objets fonctionnent correctement :
- ils ont un état
- ils ont des méthodes
- ils sont protégés contre les modifications incohérentes
Mais il reste un petit problème.
Quand on affiche un objet, Python n’est pas très sympa avec nous.
Le problème par défaut¶
Regardez ce code :
class Mamie:
def __init__(self, nom):
self.nom = nom
mamie = Mamie("Gertrude")
print(mamie)
Ce programme affiche quelque chose du genre :
<__main__.Mamie object at 0x7f8c1c2b9d90>
Autant dire que ce n’est pas très lisible.
C’est là qu’interviennent les méthodes spéciales.
Les méthodes spéciales, c’est quoi ?¶
Les méthodes spéciales sont des méthodes :
- avec un nom entouré de doubles underscores (
__) - que Python appelle automatiquement dans certains cas
Par exemple :
- quand on affiche un objet
- quand on compare deux objets
- quand on utilise certains opérateurs
On ne les appelle presque jamais directement. C’est Python qui s’en charge pour nous.
__str__ : affichage lisible pour les humains¶
La méthode __str__ définit ce qui est affiché quand on fait print(objet).
class Mamie:
def __init__(self, nom, niveau):
self.nom = nom
self.niveau = niveau
def __str__(self):
return f"Mamie {self.nom} (niveau {self.niveau})"
Maintenant :
mamie = Mamie("Gertrude", 2)
print(mamie)
affiche :
Mamie Gertrude (niveau 2)
Beaucoup mieux.
__repr__ : affichage utile pour le debug¶
__repr__ sert plutôt au développeur, pas à l’utilisateur.
Il est utilisé :
- dans la console Python
- dans les listes
- pour le debug
Exemple :
class Mamie:
def __init__(self, nom, niveau):
self.nom = nom
self.niveau = niveau
def __repr__(self):
return f"Mamie(nom={self.nom}, niveau={self.niveau})"
Maintenant :
mamies = [Mamie("Gertrude", 2), Mamie("Jeannette", 1)]
print(mamies)
affiche :
[Mamie(nom=Gertrude, niveau=2), Mamie(nom=Jeannette, niveau=1)]
Ce n’est pas joli pour un joueur, mais c’est parfait pour comprendre ce qui se passe.
__eq__ : comparer deux objets¶
Par défaut, comparer deux objets avec == teste s’ils sont le même objet en mémoire.
a = Mamie("Gertrude", 2)
b = Mamie("Gertrude", 2)
print(a == b)
Affiche :
False
Ce n’est pas toujours ce qu’on veut.
Avec __eq__, on peut définir quand deux objets sont considérés comme égaux.
class Mamie:
def __init__(self, nom, niveau):
self.nom = nom
self.niveau = niveau
def __eq__(self, other):
return self.nom == other.nom and self.niveau == other.niveau
Maintenant :
a = Mamie("Gertrude", 2)
b = Mamie("Gertrude", 2)
print(a == b)
affiche :
True
Quizz¶
Regardez ce code :
class Test:
def __init__(self, x):
self.x = x
def __eq__(self, other):
return self.x == other.x
a = Test(5)
b = Test(5)
print(a == b)
Qu’affiche ce programme ?
- *True
- False
- Une erreur
> La méthode `__eq__` définit le comportement de l’opérateur `==`.
Exercice pratique¶
Reprenez une classe que vous avez déjà écrite (par exemple Mamie).
- Ajoutez une méthode
__str__pour un affichage lisible - Ajoutez une méthode
__repr__pour le debug - Ajoutez une méthode
__eq__pour définir quand deux objets sont égaux
Testez :
print(objet)- l’affichage dans une liste
- la comparaison avec
==
Autres méthodes spéciales utiles (pour plus tard)¶
Il existe beaucoup d’autres méthodes spéciales. Vous n’avez pas besoin de toutes les connaître maintenant, mais il est bon de savoir qu’elles existent.
| Méthode | Rôle |
|---|---|
__len__ |
Permet d’utiliser len(objet) |
__getitem__ |
Permet l’indexation (objet[i]) |
__iter__ |
Permet de parcourir un objet avec une boucle for |
__lt__, __gt__ |
Comparaisons (<, >) |
__add__ |
Opérateur + |
__contains__ |
Opérateur in |
On reviendra sur certaines d’entre elles plus tard.
En résumé¶
Les méthodes spéciales permettent à vos objets de :
- mieux s’afficher
- mieux se comparer
- mieux s’intégrer au langage Python
Elles ne sont pas obligatoires,
mais elles rendent le code beaucoup plus agréable à utiliser et à comprendre.
Dans la page suivante, on va s’attaquer à un concept très important : l’héritage, et comment éviter de mal l’utiliser.