Surcharge des opérateurs en Python : redéfinir dans une classe Python les opérateurs d'addition, de multiplication et de puissance pour les nombres complexes,
Un tutoriel de Denis Hulo
Le 2022-04-10 21:11:54, par User, Rédacteur/Modérateur
Bonjour,
Après avoir défini les opérations d'addition et de multiplication pour les nombres complexes, on explique comment redéfinir les opérateurs « + », « * » et « ** » dans une classe Python à l'aide de la surcharge d'opérateurs :
Représentation algébrique d'un nombre complexe :
Enfin, pour compléter cette présentation, on explique comment ajouter à cette classe l'opérateur de comparaison « == » entre deux nombres complexes.
Bonne lecture à tous
Après avoir défini les opérations d'addition et de multiplication pour les nombres complexes, on explique comment redéfinir les opérateurs « + », « * » et « ** » dans une classe Python à l'aide de la surcharge d'opérateurs :
Représentation algébrique d'un nombre complexe :
Enfin, pour compléter cette présentation, on explique comment ajouter à cette classe l'opérateur de comparaison « == » entre deux nombres complexes.
Bonne lecture à tous
-
fred1599Expert éminentHello,
Je trouve le tutoriel très bien, et à mon sens, comme tout tutoriel, il est très rare qu'on y envoi tous les possibles...
À mon sens, cela donne envie de continuer ce qui a été commencé, en y ajoutant des opérateurs et vérifier qu'on a bien compris ce que l'auteur a écrit.
D'ailleurs c'est très bien de renvoyer vers une page donnant la liste des opérateurs existants.
Mon petit doute, est juste un détail qui a peu d'importance... le fait que se soit du niveau "confirmé" serait en fait "confirmé" si on considère un débutant Python apprenant le langage, mais "débutant" si on considère un débutant en POO avec un niveau "confirmé" en Python.
Étant donné que je considère cela comme de l'apprentissage POO et non un apprentissage Python, peut-être que je donnerai un point de précision sur l'objectif.
Techniquement c'est suffisant et il n'y a pas grand chose à y ajouter à moins d'alourdir inutilement, et de démotiver le lecteur.
C'est évidemment mon avis persole 12/04/2022 à 11:12 -
MPython AlaplanchaMembre expérimentéBonjour,
J'imagine qu'aucun tutoriel ne pourrait faire l'unanimité.
Moi non plus je ne suis pas trop math. D'ailleurs lors de mon apprentissage en python, il m'est arrivé esquiver des approches trop matheux, car je les trouvais peu ludiques et surtout je n'arrivais pas à voir en quoi cela pouvait me servir... puis vient le moment où j'ai besoin de certaine notion de math/géométrie pour réaliser un truc et là étonnamment ce que je trouvais austère l'est beaucoup moins
En ce qui concerne les nombres complexes, ce ne sont pas non plus des notions trop avancées pour matheux. Ce tutoriel reste accessible au plus grand nombrele 12/04/2022 à 11:41 -
wiztricksExpert éminent séniorLa surcharge des opérateurs, c'est un "sucre" syntaxique permettant de remplacer "3 + 5" par un appel de fonction (ici operator.add(3, 5)).
La surcharge de méthodes, c'est un polymorphisme ou plusieurs méthodes/fonctions avec le même nom mais acceptant des paramètres et des type de retour différents. Lorsqu'on appelle une de ces fonctions, le compilateur ou l'interpréteur va matcher la "bonne" en fonction du type de ses arguments.
De fait, cela n'existe pas sur Python, mais on peut faire un équivalent à partir des (*args, **kwds) reçus par une fonction ou de functools.singledispatch.
- Wle 10/04/2022 à 23:23 -
Sve@rExpert éminent séniorBonjour
Les methodes __add__ (et autres) partent toutes du principe qu'on additionne (et autres opérations) deux complexes.
Ce qui est vrai dans l'absolu car en mathématiques, tous les ensembles s'incluent les uns les autres. Les relatifs incluent les entiers en y rajoutant un sens de lecture, les décimaux incluent les relatifs en y rajoutant des parties de 10, les rationnels incluent les décimaux en y rajoutant des fractions autres que 10, les irrationnels incluent les rationnels en y rajoutant des nombres qui ne peuvent pas s'écrire sous forme de fraction, et les complexes incluent les irrationnels en y rajoutant une partie imaginaire.
Ainsi si a=2+3i et b=5, alors a+b sont bien l'addition de deux complexes au sens strict du terme puisqu'un naturel fait partire de l'ensemble des complexes. Mais ton code, lui, ne le permet pas...Code python : 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26class cComplex: def __init__(self, reel=0, img=0): (self.reel, self.img)=(reel, img) # __init__() def __str__(self): return "%s, %si" % (self.reel, self.img) # __str__() def __add__(self, other): if isinstance(other, (int, float)): other=self.__class__(other, 0) elif isinstance(other, self.__class__): pass else: raise TypeError("on ne peut pas additionner un complexe avec un {}".format(type(other).__name__)) return self.__class__(self.reel + other.reel, self.img + other.img) # ___add__() def __radd__(self, n): return self+n # cComplex() a=cComplex(5, 2) print(a) print(a+1) print(1+a+1) print(a+cComplex(2, 2)) print(a+"toto")
Ensuite malheureusement c'est un peu dommage de faire un tutoriel pour un type déjà naturellement implémenté en Python
Code python : 1
2
3
4
5
6a=5+2j print(a) print(a+1) print(1+a+1) print(a+2+2j) print(a+"toto")
Code python : 1
2
3
4
5@classmethod def fromString(cls, s): (reel, im)=...(extraction de s)... return cls(reel, img) # fromString()
le 11/04/2022 à 13:00 -
MPython AlaplanchaMembre expérimentéBonjour,
En termes de sémantique, ne serait-il pas plus juste de parler de surcharge des méthodes spéciales utilisées par les opérateurs?
...
Merci du partage (j'avais vu le blog)le 10/04/2022 à 21:53 -
papajokerExpert confirmébonjour,
les nombres complexes sont trop complexes pour moi, donc je ne parlerais que de python.
Dommage qu'il n'y ai pas de test du type dans __add__ ... __eq__
Et puisque Complexe(5) est valide, on devrait pouvoir ajouter un entier à un complexe ? ou l'inverse ...Code : 1
2
3
4
5def __radd__(self, other): if isinstance(other, int): return self.__add__(Complexe(other)) else: raise TypeError("Type non supporté pour un Complexe")
print(Complexe(2,6) +1)
- Peut-être aussi surcharger __bool__() ?
- Puisque la sortie texte est du type "x + xi" , il pourrait être amusant d'avoir un "2 + 5i" + Complexe(7,2) ?Si vous souhaitez avoir une liste plus complète des opérateurs, je vous invite à consulter cette page.le 10/04/2022 à 22:30 -
MPython AlaplanchaMembre expérimentéBonjour,
Envoyé par wiztricks Envoyé par wiztricks le 11/04/2022 à 11:10 -
UserRédacteur/ModérateurMerci à vous 3 pour vos commentaires et précisions
Je vais voir pour le lien vers la liste plus complète des opérateurs.
Cordialement.le 11/04/2022 à 12:01 -
UserRédacteur/ModérateurBonjour,
Un nombre réel étant un nombre complexe dont la partie imaginaire est nulle, je suis resté sur la définition de la somme de 2 nombres complexes qui a pour partie réelle la somme des parties réelles de ces 2 nombres, et pour partie imaginaire la somme de leurs parties imaginaires.
Je n'ai pas voulu gérer tous les cas de figures pour ne pas perdre le lecteur.
D'autre part, tu sembles vouloir gérer également les réels au niveau de l'addition, dans ce cas pourquoi ne pas le faire aussi au niveau de l'affichage :Code : 1
2
3a=cComplex(1.0,1.0) b=cComplex(1.5,-1.0) print(a+b)
2.5, 0.0i
Autant afficher simplement 2.5 dans ce cas.Ensuite malheureusement c'est un peu dommage de faire un tutoriel pour un type déjà naturellement implémenté en Python
Code python : 1
2
3
4a=5+2j print(a) print(a+1) ...
J'ai juste essayé de montrer simplement comment mettre en place ce type de surcharge, et il m'a semblé que les nombres complexes était un bon exemple pour le faire, quand bien même cela existe déjà en mieux
Cordialement.le 11/04/2022 à 17:39 -
Sve@rExpert éminent séniorA mon avis c'était le contraire, gérer tous les cas de figure pour justement montrer au lecteur qu'il faut penser à plein de trucs (et s'il est perdu il prend son temps). J'ai écrit une classe "fractions" (en fait je suis parti de cet objet pour faire cet exemple) j'ai géré le cas "-x" mais aussi le cas "+x" (opérateur "__pos__" à réécrire sinon l'expression n'est pas reconnue), le cas "x-y", le cas "-y+x" (qui, même s'il donne la même chose, n'est pas la même opération), etc...
L'affichage n'était pas le but de l'exemple. Je l'ai écrit minimaliste juste pour vérifier la validité des calculs.le 11/04/2022 à 18:08