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

Héritage et manufactures

5 réponses
Avatar
Michael Grünewald
Bonjour,

j'ai encore un petit problème de Python pour lequel j'aimerais beaucoup
obtenir vos recommendations.

J'ai une classe Educator et une manufacture de Educator, qui construit
par exemple des valeurs de Educator à partir du contenu d'un fichier:

class Educator:
def behavior(self):
print "Behave yourself!"

class EducatorReader:
def __init__(filename):

def get(self, i):
"""Get the i-th educator in our file."""
return Educator(…)

Maintenant, je dérive une classe d'Educator, en ajoutant une variable
membre _count_ en surchargeant la méthode _behavior_ pour compter le
nombre de ses appels (dans _count_). J'obtiens une classe

class StatisticalEducator(Educator):


Mon problème est: comment implémenter la manufacture
StatisticalEducatorReader? Idéalement, je voudrais pouvoir utiliser le
procédé suivant:

class StatisticalEducatorReader(EducatorReader):
def get(self, i):
x = EducatorReader.get(self, i)
«add a count field to x»
«promote x to StatisticalReader»
return x

Comment puis-je enlever les guillements dans le pseudo-code précédent?

Une implémentation alternative serait de présenter StatisticalEducator
comme un agrégat contenant un Educator et du matériel de supervision.
L'écriture de la manufacture devient facile mais la maintenance d'un
agrégat est très pénible!

Si quelqu'un avait une solution élégante (en Python, même si les
réponses dans d'autres langages m'intéressent par curiosité) je lui en
serais très reconnaissant!
--
Michael

5 réponses

Avatar
Laurent Pointal
Michael Grünewald wrote:

Bonjour,

j'ai encore un petit problème de Python pour lequel j'aimerais beaucoup
obtenir vos recommendations.

J'ai une classe Educator et une manufacture de Educator, qui construit
par exemple des valeurs de Educator à partir du contenu d'un fichier:

class Educator:
def behavior(self):
print "Behave yourself!"

class EducatorReader:
def __init__(filename):

def get(self, i):
"""Get the i-th educator in our file."""
return Educator(…)

Maintenant, je dérive une classe d'Educator, en ajoutant une variable
membre _count_ en surchargeant la méthode _behavior_ pour compter le
nombre de ses appels (dans _count_). J'obtiens une classe

class StatisticalEducator(Educator):


Mon problème est: comment implémenter la manufacture
StatisticalEducatorReader? Idéalement, je voudrais pouvoir utiliser le
procédé suivant:

class StatisticalEducatorReader(EducatorReader):
def get(self, i):
x = EducatorReader.get(self, i)
«add a count field to x»
«promote x to StatisticalReader»
return x

Comment puis-je enlever les guillements dans le pseudo-code précédent?

Une implémentation alternative serait de présenter StatisticalEducator
comme un agrégat contenant un Educator et du matériel de supervision.
L'écriture de la manufacture devient facile mais la maintenance d'un
agrégat est très pénible!

Si quelqu'un avait une solution élégante (en Python, même si les
réponses dans d'autres langages m'intéressent par curiosité) je lui en
serais très reconnaissant!



A tester:

class StatisticalEducatorReader(EducatorReader):
def get(self, i):
x = EducatorReader.get(self, i)
x.count = 0
x.__class__ = StatisticalEducator
return x

Mais gaffe que ton x n'est pas passé par les phases d'initialisation de
StatisticalEducator...


--
Laurent POINTAL -
3 allée des Orangers - 91940 Les Ulis - France
Tél. 01 69 29 06 59
Avatar
Kobayashi
Le 23/02/2012 23:08, Michael Grünewald a écrit :
Bonjour,

j'ai encore un petit problème de Python pour lequel j'aimerais beaucoup
obtenir vos recommendations.

J'ai une classe Educator et une manufacture de Educator, qui construit
par exemple des valeurs de Educator à partir du contenu d'un fichier:

class Educator:
def behavior(self):
print "Behave yourself!"

class EducatorReader:
def __init__(filename):

def get(self, i):
"""Get the i-th educator in our file."""
return Educator(…)

Maintenant, je dérive une classe d'Educator, en ajoutant une variable
membre _count_ en surchargeant la méthode _behavior_ pour compter le
nombre de ses appels (dans _count_). J'obtiens une classe

class StatisticalEducator(Educator):


Mon problème est: comment implémenter la manufacture
StatisticalEducatorReader? Idéalement, je voudrais pouvoir utiliser le
procédé suivant:

class StatisticalEducatorReader(EducatorReader):
def get(self, i):
x = EducatorReader.get(self, i)
«add a count field to x»
«promote x to StatisticalReader»
return x

Comment puis-je enlever les guillements dans le pseudo-code précédent?

Une implémentation alternative serait de présenter StatisticalEducator
comme un agrégat contenant un Educator et du matériel de supervision.
L'écriture de la manufacture devient facile mais la maintenance d'un
agrégat est très pénible!

Si quelqu'un avait une solution élégante (en Python, même si les
réponses dans d'autres langages m'intéressent par curiosité) je lui en
serais très reconnaissant!



Je suis peut-être à côté de la plaque ... mais bon :

class Educator:
pass

class EducatorReader:
factory = Educator
def get(self, i):
return self.factory()
pass

er = EducatorReader()
print er.get(0)
<__main__.Educator instance at 0x7ff445ac>

class SatisticalEducator(Educator):
pass

class SatisticalEducatorReader(EducatorReader):
factory = SatisticalEducator
def get(self, i):
x = EducatorReader.get(self, i)
x.count = i
return x
pass

ser = SatisticalEducatorReader()
print ser.get(0)
<__main__.SatisticalEducator instance at 0x7ff4476c>
Avatar
Michael Grünewald
Kobayashi wrote:
Le 23/02/2012 23:08, Michael Grünewald a écrit :
Si quelqu'un avait une solution élégante (en Python, même si les
réponses dans d'autres langages m'intéressent par curiosité) je lui en
serais très reconnaissant!



Je suis peut-être à côté de la plaque ... mais bon :



Pas du tout, c'est exactement la solution que je cherchais! D'ailleurs
je ne vois pas ce qui m'interdisait d'y penser tout seul, ce n'est
pourtant pas bien compliqué. Merci pour ton aide!

Michael
Avatar
Michael Grünewald
Laurent Pointal wrote:
A tester:

class StatisticalEducatorReader(EducatorReader):
def get(self, i):
x = EducatorReader.get(self, i)
x.count = 0
x.__class__ = StatisticalEducator
return x

Mais gaffe que ton x n'est pas passé par les phases d'initialisation de
StatisticalEducator...



Ta réponse marche, et fait exactement ce que j'avais demandé (enlever
les guillemets dans mon pseudo-code), merci!

Cependant, la solution que propose Kobayashi est probablement meilleure,
même si ce n'est pas exactementce que j'avais en tête, car elle permet
d'éviter de dupliquer le code d'initialisationde la classe dérivée. De
plus, elle marche probablement dans beaucoup de langages!
--
Michael
Avatar
Kobayashi
Le 18/03/2012 17:03, Michael Grünewald a écrit :
Kobayashi wrote:
Le 23/02/2012 23:08, Michael Grünewald a écrit :
Si quelqu'un avait une solution élégante (en Python, même si les
réponses dans d'autres langages m'intéressent par curiosité) je lui en
serais très reconnaissant!



Je suis peut-être à côté de la plaque ... mais bon :



Pas du tout, c'est exactement la solution que je cherchais! D'ailleurs
je ne vois pas ce qui m'interdisait d'y penser tout seul, ce n'est
pourtant pas bien compliqué. Merci pour ton aide!

Michael




Merci,

Si la convention de nommage est figée, on peut se passer
de définir l'attribut factory avec :

class Educator:
pass

class EducatorReader:
def get(self, i):
exec "factory = " + self.__class__.__name__[:-len("Reader")]
return factory()
pass

er = EducatorReader()
print er.get(0)

class SatisticalEducator(Educator):
pass

class SatisticalEducatorReader(EducatorReader):
def get(self, i):
x = EducatorReader.get(self, i)
x.count = i
return x
pass

ser = SatisticalEducatorReader()
print ser.get(0)