Table des matières

Méthodes magiques

Qu'est-ce

Supposons que l'on crée un objet A et que l'on crée des instances x et y de cet objet. On voudrait pouvoir les additionner.

>>> x = A()
>>> y = A()
>>> x + y
TypeError: unsupported operand type(s) for +: 'A' and 'A'

Le message d'erreur signal que l'opérateur + ne prend pas en charge notre classe A.

Il est possible de doter notre classe des caractéristiques nécessaires pour rendre cette addition possible. Et cela est valable pour d'autres opérations : -, /, %, * et aussi des opérateurs de comparaison : <, <=, >, >=, ==, != et beaucoup d'autres choses encore !

Il faut pour cela utiliser les méthodes magiques qui en Python sont toujours nommées avec des __.

Liste

En voici une liste partielle. Vous pouvez aller voir la liste complète.

new

__new__(cls). C'est une méthode de classe. Elle définit ce qui se passe on instancie un objet de la classe. La méthode par défaut se contente d'appeler __init__

str

__str__(self). Appelée quand on demande une conversion de l'objet en chaîne de caractères. C'est le cas quand on appelle la fonction print.

repr

__repr__(self). Ressemble à la précédente mais est utilisée lors de l'affichage en console.

add

__add__(A, B). Quant on ajoute A + B, alors on appelle la méthode pour A.

sub, mul, div

Même chose pour :

incrément et autre

On aime utilisé des opérateurs comme +=. Si on demande A += B, il faudra définir __iadd__(A, B).

Même chose avec __isub__, __imul__, __idiv__ et __ifloordiv__.

transtypages

De même que l'on peut convertir en str avec __str__ on peut prendre en charge le transtypage en int, float et complex avec __int__, __float__ et __complex__.

valeur absolue

__abs__(self)

Comparaison

Exemple

Pour illustrer, donnons l'exemple de vecteurs 2D que l'on veut pouvoir ajouter et dont on veut pouvoir trouver la norme en utilisant abs.

from math import sqrt

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __add__(A, B):
        x = self.x + B.x
        y = self.y + B.y
        return Vector(x, y)

    def __sub__(A, B):
        x = self.x - B.x
        y = self.y - B.y
        return Vector(x, y)
        
    def __abs__(self):
        return sqrt(self.x**2 + self.y**2)
    
    def __str__(self):
        return "({} ; {})".format(self.x, self.y)

if __name__ == "__main__":        
    # exemple d'utilisation
    a = Vector(3, 4)
    b = Vector(5, -2)
    c = a + b
    print(c) # affiche "(8 ; 2)"
    d = a - b
    print(d) # affiche "(-2 ; 6)"
    l = abs(a)
    print(l) # affiche 5.0