Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Surcharge de fonctions

8 réponses
Avatar
Guillaume Bouchard
Bonjour/soir.

J'ai écrit un module obscure qui fait certains traitements sur des
entiers dont des racines carré (et qui renvoie des floats)

Puis j'ai crée par la suite un type relatif avec puissance. C'est en
fait un nombre de la forme (a / b ) ^ ( c / d) avec a,b,c,d integers.
Cela me permet de faire mes calculs de façon plus formel et d'avoir dans
tous les cas les vrais valeurs qui me reviennent.

J'ai donc voulu envoyer dans les classes de mon premier module ce fameux
type. Cependant math.sqrt ne travail qu'avec les integer ou float. J'ai
donc surchargé mon type relatif avec une classe sqrt. Mais forcement
cela ne remplace pas la methode de math.sqrt.

J'ai donc fait un truc ignoble du style math.sqrt = manouvellefonction.

Cela fonctionne, mais cela pourrie math.sqrt de son comportement normal
pour le reste (Il faut que je bidouille dans ma nouvelle fonction en
fonction du type, bref c'est un peu le bordel)

Bref, conaissez vous un moyen plus propre de dire à Python que pour un
type donné, le comportement de certains fonctions doit changer ?

Par contre j'ai été trés ettoné de pouvoir redefinir math.sqrt

>>> import math
>>> math.sqrt(5)
2.2360679774997898
>>> def toto(a):
... return a * 2
...
>>> math.sqrt = toto
>>> math.sqrt(5)
10

Alors que
>>> int.__neg__ = toto
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: can't set attributes of built-in/extension type 'int'

Sachant que pour moi math était une lib built-in aussi...

Merci.

--
Guillaume.

8 réponses

Avatar
Amaury Forgeot d'Arc
Bonjour/soir.

J'ai écrit un module obscure qui fait certains traitements sur des
entiers dont des racines carré (et qui renvoie des floats)

Puis j'ai crée par la suite un type relatif avec puissance. C'est en
fait un nombre de la forme (a / b ) ^ ( c / d) avec a,b,c,d integers.
Cela me permet de faire mes calculs de façon plus formel et d'avoir dans
tous les cas les vrais valeurs qui me reviennent.

J'ai donc voulu envoyer dans les classes de mon premier module ce fameux
type. Cependant math.sqrt ne travail qu'avec les integer ou float. J'ai
donc surchargé mon type relatif avec une classe sqrt. Mais forcement
cela ne remplace pas la methode de math.sqrt.

J'ai donc fait un truc ignoble du style math.sqrt = manouvellefonction.

Cela fonctionne, mais cela pourrie math.sqrt de son comportement normal
pour le reste (Il faut que je bidouille dans ma nouvelle fonction en
fonction du type, bref c'est un peu le bordel)

Bref, conaissez vous un moyen plus propre de dire à Python que pour un
type donné, le comportement de certains fonctions doit changer ?


Je propose de créer un nouveau module, mymath.py:
from math import *
def sqrt(x):
...


Par contre j'ai été trés ettoné de pouvoir redefinir math.sqrt

import math
math.sqrt(5)
2.2360679774997898



def toto(a):
... return a * 2



...
math.sqrt = toto
math.sqrt(5)
10




Alors que
int.__neg__ = toto
Traceback (most recent call last):



File "<stdin>", line 1, in ?
TypeError: can't set attributes of built-in/extension type 'int'

Sachant que pour moi math était une lib built-in aussi...


int est un type, et on peut forcer un type à ne pas avoir de
dictionnaire pour des raisons de performance.
math est un module, il a donc forcément un dictionnaire (__dict__) que
l'on peut modifier.


Merci.



--
Amaury




Avatar
Guillaume Bouchard
Amaury Forgeot d'Arc wrote:
Je propose de créer un nouveau module, mymath.py:
from math import *
def sqrt(x):
...


Excuse moi je ne vois pas en quoi cela m'aide dans mon problème ? Comme
je n'ai pas acces à la modification de la classe, je ne peux pas lui
faire remplacer l'appel à math.sqrt par mymath.sqrt.

--
Guillaume.

Avatar
Ahmed MOHAMED ALI
Bonjour,

cela ne remplace pas la methode de math.sqrt.
J'ai donc fait un truc ignoble du style math.sqrt = manouvellefonction.


Tu peux définir une fonction globale sqrt qui accepte les types de bases et
ton nouveau type.

def manouvellefonction_sqrt(x):
....
return valeur

def sqrt(x):
try:
resultat= math.sqrt(x)
except TypeError:
resultat= manouvellefonction(x) #on suppose que x est du bon type
return resultat

Ahmed

"Guillaume Bouchard" wrote in message
news:d7ijpn$ljf$
Bonjour/soir.

J'ai écrit un module obscure qui fait certains traitements sur des
entiers dont des racines carré (et qui renvoie des floats)

Puis j'ai crée par la suite un type relatif avec puissance. C'est en
fait un nombre de la forme (a / b ) ^ ( c / d) avec a,b,c,d integers.
Cela me permet de faire mes calculs de façon plus formel et d'avoir dans
tous les cas les vrais valeurs qui me reviennent.

J'ai donc voulu envoyer dans les classes de mon premier module ce fameux
type. Cependant math.sqrt ne travail qu'avec les integer ou float. J'ai
donc surchargé mon type relatif avec une classe sqrt. Mais forcement
cela ne remplace pas la methode de math.sqrt.

J'ai donc fait un truc ignoble du style math.sqrt = manouvellefonction.

Cela fonctionne, mais cela pourrie math.sqrt de son comportement normal
pour le reste (Il faut que je bidouille dans ma nouvelle fonction en
fonction du type, bref c'est un peu le bordel)

Bref, conaissez vous un moyen plus propre de dire à Python que pour un
type donné, le comportement de certains fonctions doit changer ?

Par contre j'ai été trés ettoné de pouvoir redefinir math.sqrt

import math
math.sqrt(5)
2.2360679774997898



def toto(a):
... return a * 2



...
math.sqrt = toto
math.sqrt(5)
10




Alors que
int.__neg__ = toto
Traceback (most recent call last):



File "<stdin>", line 1, in ?
TypeError: can't set attributes of built-in/extension type 'int'

Sachant que pour moi math était une lib built-in aussi...

Merci.

--
Guillaume.





Avatar
Do Re Mi chel La Si Do
Bonjour !


J'ai donc fait un truc ignoble du style math.sqrt = manouvellefonction




Cela n'est pas ignoble, mais peut-être un peu lourd, auquel cas, on appelle
ça une surcharge pondérale ;o)



Sinon, la soluce d'Ahmed me semble bien répondre au besoin.



@-salutations

Michel Claveau



Avatar
Guillaume Bouchard
Ahmed MOHAMED ALI wrote:
Tu peux définir une fonction globale sqrt qui accepte les types de bases et
ton nouveau type.


et je surcharge le module math avec cette fonction. Idee acceptable
seulement :

Dans le cas ou la classe en question fasse son /import math/ à
l'interieur, la nouvelle fonction math.sqrt est ignorer car remplacer
par la fonction math.sqrt definie dans la classe.

(Il ne faut pas oublié que je me base dans l'optique que je n'ai aucun
moyen de modifier le code source de la classe en question)

Bref, j'ai un debut de reponse, mais perfectible. Y a t'il une meilleur
solution ?

--
Guillaume

Avatar
kaerbuhez
Bonjour !



J'ai donc fait un truc ignoble du style math.sqrt = manouvellefonction





Cela n'est pas ignoble, mais peut-être un peu lourd, auquel cas, on appelle
ça une surcharge pondérale ;o)



;-)) Excellent !

Sinon, il vaudrait mieux utiliser les termes appropriés : il est
question ici de rebinding (? en français) en non d'overloading
(surcharge) : 2 concepts essentiellement différents. Pensons aux
nombreuses personnes (et surtout aux nombreux débutants) qui lisent ou
liront ce fil.


Sinon, la soluce d'Ahmed me semble bien répondre au besoin.


Oui, rien à ajouter non plus.



@-salutations

Michel Claveau










Avatar
Amaury Forgeot d'Arc
Amaury Forgeot d'Arc wrote:

Je propose de créer un nouveau module, mymath.py:
from math import *
def sqrt(x):
...



Excuse moi je ne vois pas en quoi cela m'aide dans mon problème ? Comme
je n'ai pas acces à la modification de la classe, je ne peux pas lui
faire remplacer l'appel à math.sqrt par mymath.sqrt.



- Si tu as accès au code source de ta classe, il suffit de remplacer
"import math" par "import mymath as math".

- Si le module est vraiment obscur, il reste la possibilité de le
changer comme ceci:
import moduleObscur, mymath
moduleObscur.math = mymath
Ainsi, on a simplement remplacé la variable "math" dans le module, sans
modifier le 'vrai' module math.

J'espère ne pas être trop obscur moi-même...

--
Amaury


Avatar
Guillaume Bouchard
Amaury Forgeot d'Arc wrote:
- Si tu as accès au code source de ta classe, il suffit de remplacer
"import math" par "import mymath as math".


J'y ai acces, mais je me demande comment faire pour le jour ou je n'y
aurais plus access.

- Si le module est vraiment obscur, il reste la possibilité de le
changer comme ceci:
import moduleObscur, mymath
moduleObscur.math = mymath
Ainsi, on a simplement remplacé la variable "math" dans le module, sans
modifier le 'vrai' module math.


Et dans le cas ou l'import du module math en question c'est fait DANS
une fonction de la class directement ? J'ai esseyer sans trop de succes
moduleObscur.function.math. Voir même dans le cas ou ce fut un rom math
import sqrt DANS la function ?

J'espère ne pas être trop obscur moi-même...


Non trés clair, merci.

--
Guillaume.