====== 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 [[https://www.tutorialsteacher.com/python/magic-methods-in-python|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 : * la soustraction ''%%__sub__(A, B)%%'', * multiplication ''%%__mul__(A, B)%%'', * la division ''%%__div__(A, B)__%%'', * la division entière (''%%//%%'') ''%%__floordiv__(A, B)%%'', * le modulo ''%%__mod__(A, B)__%%'', * la puissance (''%%**%%'') ''%%__pow__(A, B)%%''. == 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 == * ''%%A >= B%%'' -- //greater or equal// -- ''%%__ge__(A, B)%%'' * ''%%A <= B%%'' -- //lower or equal// -- ''%%__le__(A, B)%%'' * ''%%A > B%%'' -- //greater than// -- ''%%__gt__(A, B)%%'' * ''%%A < B%%'' -- //lower than// -- ''%%__lt__(A, B)%%'' * ''%%A == B%%'' -- //equal// -- ''%%__eq__(A, B)%%'' * ''%%A != B%%'' -- //not equal// -- ''%%__ne__(A, B)%%'' ===== 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