1.6. La surcharge d’opérateurs¶
Nous avons maintenant montré que les classes permettaient de créer des types bien plus sophistiqués et puissants que les types élémentaires. Cependant, comme nous allons le voir, nos objets interagissent pour l’instant plutôt mal avec l’écosystème de Python.
Définissons une classe qui représente un nombre complexe, avec deux attributs de type float
pour stocker la partie réelle et la partie imaginaire, ainsi que quelques méthodes utiles.
import math
class Complex:
def __init__(self, real, img):
self.real = real
self.img = img
def magnitude(self):
return math.sqrt(self.real ** 2 + self.img ** 2)
def conjugate(self):
return Complex(self.real, -self.img)
a = Complex(4, 2)
print(a.real)
print(a.img)
print(a.magnitude())
print(a.conjugate().img)
4
2
4.47213595499958
-2
Les attributs et méthodes de l’objet se comportent bien comme prévu. Essayons maintenant d’afficher la valeur de l’objet et d’additionner deux nombres complexes entre eux.
print(a)
c = Complex(-3, 8)
print(a + c)
<__main__.Complex object at 0x7f568703bf10>
Traceback (most recent call last):
File "<input>", line...
print(a + c)
TypeError: unsupported operand type(s) for +: 'Complex' and 'Complex'
La console affiche <__main__.Complexe object at ...>
(résultat variable) au lieu d’une représentation mathématique classique comme 4 + 2i
.
Pire encore, impossible d’additionner entre eux deux de nos nombres complexes à l’aide de l’opérateur +
, comme l’indique le message d’erreur.
Pour cause, Python ne sait pas afficher nos objets ni les additionner, car on ne lui a pas expliqué comment faire. Comme pour certains objets (mais pas tous !) les opérateurs de Python se montrent très pratiques, il existe un moyen de spécifier comment additionner, comparer, afficher, etc. nos objets personnalisés. On appelle cela la surcharge d’opérateurs.
1.6.1. La représentation textuelle¶
Pour qu’un objet puisse être converti en chaîne de caractères, et ainsi lui offrir une représentation textuelle, il faut mettre en œuvre la méthode spéciale __str__()
.
Elle est appelée lorsque l’objet doit être converti en chaîne de caractère et elle renvoie le résultat.
Sa mise en œuvre par défaut renvoie l’adresse mémoire à laquelle l’objet est stocké (d’où l’affichage cryptique que nous avons rencontré précédemment).
class Complex:
def __init__(self, real, img):
self.real = real
self.img = img
# fonction appelée chaque fois que l'on doit convertir l'objet en chaîne de caractères
def __str__(self):
# on renvoie une représentation textuelle
return f"{self.real} + {self.img}i"
a = Complex(4, 2)
b = Complex(-3, 8)
print(a)
print(b)
4 + 2i
-3 + 8i
1.6.2. La surcharge des opérateurs arithmétiques¶
La surcharge des opérateurs mathématiques se fait de manière similaire à celle de la représentation textuelle, en mettant en œuvre les méthodes spéciales dédiées. La seule différence notable est que ces méthodes spéciales possèdent un argument prenant la valeur du second opérande.
Méthodes de surcharge des opérateurs arithmétiques
Opérateur arithmétique |
Méthode spéciale |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Voyons un exemple avec l’opérateur d’addition.
class Complex:
def __init__(self, real, img):
self.real = real
self.img = img
def __str__(self):
return f"{self.real} + {self.img}i"
def __add__(self, other):
return Complex(self.real + other.real, self.img + other.img)
a = Complex(4, 2)
b = Complex(-3, 8)
print(a + b)
1 + 10i
Dans cet exemple, l’instruction print(a + b)
appelle la méthode d’addition __add__()
pour additionner les deux nombres complexes puis la méthode de conversion __str__()
pour afficher le résultat.
1.6.3. La surcharge des opérateurs de comparaison¶
La surcharge des opérateurs de comparaison se fait de la même manière que pour les opérateurs arithmétiques.
Méthodes de surcharge des opérateurs de comparaison
Opérateur de comparaison |
Méthode spéciale |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Voyons un exemple avec l’opérateur d’égalité.
class Complex:
def __init__(self, real, img):
self.real = real
self.img = img
def __eq__(self, other):
return self.real == other.real and self.img == other.img
a = Complex(4, 2)
b = Complex(-3, 8)
print(a == b)
print(b == Complex(-3, 8))
False
True
1.6.4. Opérateurs supplémentaires¶
Les autres opérateurs du langage Python peuvent également être surchargés. Nous résumons ci-dessous les méthodes spéciales correspondantes.
Méthodes de surcharge des opérateurs d’assignation
Opérateur d’assignation |
Méthode spéciale |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Méthodes de surcharge des opérateurs unaires
Opérateur unaire |
Méthode spéciale |
---|---|
|
|
|
|
|
|