Surcharge des opérateurs

Définition

Une classe peut implémenter certaines opérations que l'on invoque par une syntaxe spéciale (telles que les opérations arithmétiques ou la découpe en tranches) en définissant des méthodes aux noms particuliers. C'est l'approche utilisée par Python pour la surcharge d'opérateur, permettant à une classe de définir son propre comportement vis-à-vis des opérateurs du langage.

ExempleSurcharge de l'opérateur +

La méthode __add__ permet de surcharger l'opérateur +. Dans l'exemple suivant, une classe Fraction est définie et l'opérateur __add__ est surchargé.

1
class Fraction:
2
    def __init__(self, p, q):
3
        self.numerateur = p
4
        self.denominateur = q
5
    def __add__(self, b):
6
        return Fraction(self.numerateur * b.denominateur + 
7
            b.numerateur * self.denominateur, 
8
            self.denominateur * b.denominateur)        

Une fois la classe définie, on peut écrire :

ComplémentSurcharge d'opérateur pour d'autres types de données

Lors de l'ajout d'un entier à une fraction on a un message d'erreur.

Pour éviter cela, il faut prévoir la surcharge pour chaque type d'opération

1
class Fraction:
2
    def __init__(self, p, q):
3
        self.numerateur = p
4
        self.denominateur = q
5
    def __add__(self, b):
6
        if isinstance(b,int):
7
            b = Fraction(b, 1)
8
        if isinstance(b,Fraction):
9
            return Fraction(self.numerateur * b.denominateur + 
10
                b.numerateur * self.denominateur, 
11
                self.denominateur * b.denominateur)
12
        raise(NotImplemented(type(b) + ' not implemented for add Fraction'))
13

Le résultat est maintenant correct avec l'addition à droite pour un nombre entier.

ComplémentSurcharge d'opérateur les opérande

Si l'ordre des opérations est inversé alors une erreur se produit.

Pour gérer l'ordre des opérandes, il faut surcharger la méthode __radd__ (r pour reverse ou renversé).

1
class Fraction:
2
    def __init__(self, p, q):
3
        self.numerateur = p
4
        self.denominateur = q
5
    def __add__(self, b):
6
        if isinstance(b,int):
7
            b = Fraction(b, 1)
8
        if isinstance(b,Fraction):
9
            return Fraction(self.numerateur * b.denominateur + 
10
                b.numerateur * self.denominateur, 
11
                self.denominateur * b.denominateur)
12
        raise(NotImplemented(type(b) + ' not implemented for add Fraction'))
13
    def __radd__(self, b):
14
        if isinstance(b,int):
15
             return Fraction(b, 1) + self
16
        else:
17
            raise(NotImplemented(type(self) + ' not implemented for add Fraction'))
18