OVH Cloud OVH Cloud

Heritage de methode

31 réponses
Avatar
Francois
Bonjour,

J'ai une classe 'Vecteur' qui m'intéresse et à laquelle je souhaite
rajouter quelques méthodes.
Comme cette classe est 'figée' et que je ne peux pas y toucher, j'ai
pensé créer une classe 'MonVecteur' qui dérive de cette classe et à
laquelle je rajoute mes propres méthodes.

En particulier je souhaiterais néanmoins que 'MonVecteur' dispose des
mêmes méthodes que 'Vecteur', pour les additions, les
multiplications, les normalisations, etc...
Le problème est que ces méthodes _créent_ un objet de classe 'Vecteur'
et non pas 'MonVecteur' lorsque j'essaye par exemple d'additioner deux
objets de classe 'MonVecteur'.

J'espère avoir été clair, donc si quelqu'un avait une idée pour
résoudre mon problème...

Merci d'avance,

10 réponses

1 2 3 4
Avatar
Amaury
Bonjour,
Bonjour,



J'ai une classe 'Vecteur' qui m'intéresse et à laquelle je souhaite
rajouter quelques méthodes.
Comme cette classe est 'figée' et que je ne peux pas y toucher, j'ai
pensé créer une classe 'MonVecteur' qui dérive de cette classe et à
laquelle je rajoute mes propres méthodes.

En particulier je souhaiterais néanmoins que 'MonVecteur' dispose des
mêmes méthodes que 'Vecteur', pour les additions, les
multiplications, les normalisations, etc...
Le problème est que ces méthodes _créent_ un objet de classe 'Vecteur'
et non pas 'MonVecteur' lorsque j'essaye par exemple d'additioner deux
objets de classe 'MonVecteur'.


Alors il te faut dériver aussi toutes les fonctions qui font l'addition,
la multiplication... :

class MonVecteur(Vecteur):
...
def __add__(self, other):
vec = Vecteur.__add__(self, other)
vec.__class__ = MonVecteur
return vec

On triche (un peu) en ne faisant que changer la classe de l'objet, mais
si tu n'as fait que rajouter des méthodes, tout se passera bien.

Comme cette classe est 'figée' ...
En python, rien n'est figé ! Il est parfaitement possible de modifier

une classe existante, d'ajouter des méthodes dynamiquement !

def nouvelleMethode(self, x, y):
...
Vecteur.nouvelleMethode = nouvelleMethode

Et bye bye, MonVecteur ! Mais c'est à utiliser avec extrême précaution.

Bonne chance,

--
Amaury

Avatar
Laurent Pointal
Francois wrote:
Bonjour,

J'ai une classe 'Vecteur' qui m'intéresse et à laquelle je souhaite
rajouter quelques méthodes.
Comme cette classe est 'figée' et que je ne peux pas y toucher, j'ai
pensé créer une classe 'MonVecteur' qui dérive de cette classe et à
laquelle je rajoute mes propres méthodes.

En particulier je souhaiterais néanmoins que 'MonVecteur' dispose des
mêmes méthodes que 'Vecteur', pour les additions, les
multiplications, les normalisations, etc...
Le problème est que ces méthodes _créent_ un objet de classe 'Vecteur'
et non pas 'MonVecteur' lorsque j'essaye par exemple d'additioner deux
objets de classe 'MonVecteur'.

J'espère avoir été clair, donc si quelqu'un avait une idée pour
résoudre mon problème...

Merci d'avance,


Heu, pas testé et je n'ai aucune idée si ça marche...

Redéfinir Vecteur.__new__ pour qu'il retourne un MonVecteur.

Bons tests

A+

Avatar
Francois

J'ai une classe 'Vecteur' qui m'intéresse et à laquelle je souhaite
rajouter quelques méthodes.
Comme cette classe est 'figée' et que je ne peux pas y toucher, j'ai
pensé créer une classe 'MonVecteur' qui dérive de cette classe et à
laquelle je rajoute mes propres méthodes.

En particulier je souhaiterais néanmoins que 'MonVecteur' dispose
des mêmes méthodes que 'Vecteur', pour les additions, les
multiplications, les normalisations, etc...
Le problème est que ces méthodes _créent_ un objet de classe
'Vecteur' et non pas 'MonVecteur' lorsque j'essaye par exemple
d'additioner deux objets de classe 'MonVecteur'.


Alors il te faut dériver aussi toutes les fonctions qui font
l'addition, la multiplication... :


Ouh là là...


class MonVecteur(Vecteur):
...
def __add__(self, other):
vec = Vecteur.__add__(self, other)
vec.__class__ = MonVecteur
return vec

On triche (un peu) en ne faisant que changer la classe de l'objet,
mais si tu n'as fait que rajouter des méthodes, tout se passera bien.


Superbe astuce ! Merci du tuyau !

Comme cette classe est 'figée' ...
En python, rien n'est figé ! Il est parfaitement possible de modifier

une classe existante, d'ajouter des méthodes dynamiquement !

def nouvelleMethode(self, x, y):
...
Vecteur.nouvelleMethode = nouvelleMethode

Et bye bye, MonVecteur ! Mais c'est à utiliser avec extrême
précaution.


Ah ! C'est exactement ce dont j'avais besoin et je ne savais même
pas que c'était possible (j'ai toujours tendance à sous-estimer Python,
je ne sais pas pourquoi).
Quelles sont les précautions à prendre ?

Merci de ton aide,


Avatar
Francois
On Fri, 25 Nov 2005 09:41:57 +0100, Laurent Pointal

J'ai une classe 'Vecteur' qui m'intéresse et à laquelle je souhaite
rajouter quelques méthodes.
Comme cette classe est 'figée' et que je ne peux pas y toucher, j'ai
pensé créer une classe 'MonVecteur' qui dérive de cette classe et à
laquelle je rajoute mes propres méthodes.

En particulier je souhaiterais néanmoins que 'MonVecteur' dispose
des mêmes méthodes que 'Vecteur', pour les additions, les
multiplications, les normalisations, etc...
Le problème est que ces méthodes _créent_ un objet de classe
'Vecteur' et non pas 'MonVecteur' lorsque j'essaye par exemple
d'additioner deux objets de classe 'MonVecteur'.



Heu, pas testé et je n'ai aucune idée si ça marche...

Redéfinir Vecteur.__new__ pour qu'il retourne un MonVecteur.



Hélas je ne peux absolument pas toucher à la classe Vecteur elle-même
(provient d'une bibliothèque figée et maintenue par quelqu'un d'autre).

Merci quand même,


Avatar
Christophe Cavalaria
Francois wrote:

On Fri, 25 Nov 2005 09:41:57 +0100, Laurent Pointal

J'ai une classe 'Vecteur' qui m'intéresse et à laquelle je souhaite
rajouter quelques méthodes.
Comme cette classe est 'figée' et que je ne peux pas y toucher, j'ai
pensé créer une classe 'MonVecteur' qui dérive de cette classe et à
laquelle je rajoute mes propres méthodes.

En particulier je souhaiterais néanmoins que 'MonVecteur' dispose
des mêmes méthodes que 'Vecteur', pour les additions, les
multiplications, les normalisations, etc...
Le problème est que ces méthodes _créent_ un objet de classe
'Vecteur' et non pas 'MonVecteur' lorsque j'essaye par exemple
d'additioner deux objets de classe 'MonVecteur'.



Heu, pas testé et je n'ai aucune idée si ça marche...

Redéfinir Vecteur.__new__ pour qu'il retourne un MonVecteur.



Hélas je ne peux absolument pas toucher à la classe Vecteur elle-même
(provient d'une bibliothèque figée et maintenue par quelqu'un d'autre).

Merci quand même,


A mon avis, la solution la plus propre ici consiste soit à :
- encapsuler Vecteur dans MonVecteur et ne pas faire d'heritage.
- fournir les fonctionalités de MonVecteur en tant que simples fonctions
d'un module python.

Pas besoin de tout voir en objet et en heritage, surtout dans ce cas. En
particulier, je dirais qu'en conception objet, à moins d'avoir besoin de
polymorphisme il faut absolument éviter l'heritage ;)



Avatar
Do Re Mi chel La Si Do
Bonjour !

En gros, tu suggères de systématiser la délégation. C'est ça ?
Mais, par rapport à l'héritage, il y aura une différence, si la classe
Vecteur évolue (si une nouvelle version contient une nouvelle fonction, par
exemple).

@-salutations

Michel Claveau
Avatar
Christophe Cavalaria
Do Re Mi chel La Si Do wrote:

Bonjour !

En gros, tu suggères de systématiser la délégation. C'est ça ?
Mais, par rapport à l'héritage, il y aura une différence, si la classe
Vecteur évolue (si une nouvelle version contient une nouvelle fonction,
par exemple).

@-salutations

Michel Claveau


Bien sur, car quand la classe vector evolue, tu dois surveiller toute
nouvelle méthode et chercher celles qui renvoient un nouveau objet Vector
pour les remplacer par des versions qui renvoient un objet MonVector de tt
façon.

Une autre possibilité aurait été si la classe Vector fesait self.__class__()
pour construire ses nouvelles valeurs mais je doute que ce soit le cas.
Dans ce dernier cas, il est envisageable d'hériter.

De toute façon, plus on n'y pense et plus on voit que les classes de type
vector/string/num etc... ne sont pas de bons candidats pour faire de
l'heritage. Trop de problèmes d'impedence entre l'ancien type et le nouveau
type.

Avatar
Francois
On Sat, 26 Nov 2005 00:16:54 +0100, Christophe Cavalaria

J'ai une classe 'Vecteur' qui m'intéresse et à laquelle je
souhaite rajouter quelques méthodes.
Comme cette classe est 'figée' et que je ne peux pas y toucher,
j'ai pensé créer une classe 'MonVecteur' qui dérive de cette
classe et à laquelle je rajoute mes propres méthodes.

En particulier je souhaiterais néanmoins que 'MonVecteur' dispose
des mêmes méthodes que 'Vecteur', pour les additions, les
multiplications, les normalisations, etc...
Le problème est que ces méthodes _créent_ un objet de classe
'Vecteur' et non pas 'MonVecteur' lorsque j'essaye par exemple
d'additioner deux objets de classe 'MonVecteur'.



Heu, pas testé et je n'ai aucune idée si ça marche...

Redéfinir Vecteur.__new__ pour qu'il retourne un MonVecteur.



Hélas je ne peux absolument pas toucher à la classe Vecteur
elle-même (provient d'une bibliothèque figée et maintenue par
quelqu'un d'autre).

Merci quand même,


A mon avis, la solution la plus propre ici consiste soit à :
- encapsuler Vecteur dans MonVecteur et ne pas faire d'heritage.
- fournir les fonctionalités de MonVecteur en tant que simples
fonctions d'un module python.

Pas besoin de tout voir en objet et en heritage, surtout dans ce cas.
En particulier, je dirais qu'en conception objet, à moins d'avoir
besoin de polymorphisme il faut absolument éviter l'heritage ;)



Quel est l'intérêt d'encapsuler Vecteur dans MonVecteur si je ne fais
pas d'héritage ?
Tu veux juste dire importer la classe en même temps que
d'autres fonctions additionnelles quand j'importe MonVecteur ?

Cela m'embête un peu de mélanger méthodes et fonctions lorsque les
fonctions devraient en toute logique être des méthodes, j'essaye
d'éviter quand je peux, sinon on arrive vite à des horreurs comme :

fonctionE(fonctionC(toto.methodeA().methodeB()).methodeD()))

alors que je trouve beaucoup plus simple un :

toto.methodeA().methodeB().methodeC().methodeD().methodeE()

Amaury proposait d'ajouter les méthodes à la classe Vecteur, à la
volée, qu'est-ce qui ne va pas avec ça ?

Merci pour tes réponses,




Avatar
Francois
On Sat, 26 Nov 2005 09:42:20 +0100, "Do Re Mi chel La Si Do"

Bonjour !

En gros, tu suggères de systématiser la délégation. C'est ça ?
Mais, par rapport à l'héritage, il y aura une différence, si la
classe Vecteur évolue (si une nouvelle version contient une nouvelle
fonction, par exemple).



C'est exactement mon problème ; je ne souhaite pas courir en
permanence derrière la classe Vecteur qui évolue sans cesse...

Avatar
Francois
On Sat, 26 Nov 2005 10:51:27 +0100, Christophe Cavalaria

En gros, tu suggères de systématiser la délégation. C'est ça ?
Mais, par rapport à l'héritage, il y aura une différence, si la
classe Vecteur évolue (si une nouvelle version contient une
nouvelle fonction, par exemple).



Bien sur, car quand la classe vector evolue, tu dois surveiller toute
nouvelle méthode et chercher celles qui renvoient un nouveau objet
Vector pour les remplacer par des versions qui renvoient un objet
MonVector de tt façon.

Une autre possibilité aurait été si la classe Vector fesait
self.__class__() pour construire ses nouvelles valeurs mais je doute
que ce soit le cas. Dans ce dernier cas, il est envisageable
d'hériter.

De toute façon, plus on n'y pense et plus on voit que les classes de
type vector/string/num etc... ne sont pas de bons candidats pour
faire de l'heritage. Trop de problèmes d'impedence entre l'ancien
type et le nouveau type.


Si la classe Vecteur faisait un self.__class__() avant toute création
de nouvelles valeurs, cela résoudrait le problème c'est ça ?
Est-ce que cela vaut-il l'effort d'inclure cela dans tous ce que je
développe ? Quels sont les inconvénients ?

J'aime assez bien le principe...

Merci !


1 2 3 4