Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Comment rassembler mes méthodes ?

+1 vote

J'ai une classe qui a un bon nombre de méthodes presque similaire, et je me demander par quel moyen je pouvais les rassembler.

Je vous montre :

class Negatif(Element):
    def __init__(self, element):
       assert isinstance(element, Element), "L'élément donné est mauvais : " + element
       Element.__init__(self)
       self.element = element
    def idempotencer(self):
       return self.element.idempotencer()
    def associer(self):
       return self.element.associer()
    def involuer(self):
       if type(self.element) is Negatif:
           return self.element.element
       else:
           return Negatif(self.element.involuer())
    def distribuer_and(self):
       return self.element.distribuer_and()
    def distribuer_or(self):
       return self.element.distribuer_or()
    def morganiser(self):
       element_morganise = self.element.morganiser()
       if type(self.element) is Or:
           return And(*[-x for x in element_morganise.elements]).morganiser()
       if type(self.element) is And:
           return Or(*[-x for x in element_morganise.elements]).morganiser()
       return element_morganise.associer()
    def materialiser(self):
       return self.element.materialiser()
    def materialiser_double(self):
       return self.element.materialiser_double()
    def normaliser(self):
       return self.element.normaliser()
    def est(self, other):
       if other.__class__ is Negatif:
           return True if self.element.est(other.element) else False
       else:
           return False

Ici, on peut voir qu'il y a 8 méthodes tenant sur une ligne : idempotencer, associer, involuer, distribuer_and, distribuer_or, materialiser et materialiser_double et normaliser.

Elles sont presque pareilles, de cette forme:

return self.element.nomdela_methode()

Puis-je les rassembler pour en avoir une seule ?

demandé 24-Mar par Andy (314 points)
edité 24-Mar par foxmask

puisque vous héritez de Element, je suppose que les 7 méthodes (d'une ligne) retournant les méthodes de la classe mère, ne sont pas surchargées, non ? Si c'est le cas, on peut instancier Negatif et utiliser les méthodes de la classe mère non ?

Si, elles sont surchargées. Element à elle même beaucoup de fonction d'une seule ligne qui se ressemble.


class Element:
def init(self):
pass
def idempotencer(self):
return self
def associer(self):
return self
def involuer(self):
return self
def distribuerand(self):
return self
def distribuer
or(self):
return self
def morganiser(self):
return self
def materialiser(self):
return self
def materialiserdouble(self):
return self
def normaliser(self):
print("Formule initiale : " + str(self))
self = self.materialiser
double()
print("Formule double implication materialisée : " + str(self))
self = self.materialiser()
print("Formule implication materialisée : " + str(self))
self = self.involuer()
print("Formule involuée : " + str(self))
self = self.morganiser()
print("Formule morganisée : " + str(self))
self = self.distribuer_or()
print("Formule distribuée : " + str(self))
return self
def add(self, other):
return Or(self, other).associer().idempotencer()
def mul(self, other):
return And(self, other).associer().idempotencer()
def neg(self):
return Negatif(self).involuer()
def rshift(self, other):
return Implication(self, other)
def mod(self, other):
return DoubleImplication(self, other)
def str(self):
return str(self)

je trouve que chacune d'elle à droite d'être là . Simplifier pour simplifier n'aurait pas de sens si c'est une classe type "Interface".

Même pour la classe Négatif ?

Pour négative , je vous renvoie à mon commentaire 1 ;)

puisque vous héritez de Element, je suppose que les 7 méthodes (d'une ligne) retournant les méthodes de la classe mère, ne sont pas surchargées, non ?

Que souhaitez vous dire par "retourner les méthodes de la classes mère" ? Mes méthodes n'utilise ni super() ni return Element.ma_methode()

Par contre effectivement j'ai fait une erreur lors de mon premier commentaire (en faite j'ai confondu).
Il n'existe pas de classe fille de Négatif, surchargeant ses méthodes d'une ligne. Mais j'ai d'autre classes, par exemple FormuleMultiElements, héritant de Element et qui possèdent deux classes filles (And et Or), surchargeant ses propres méthodes d'une ligne. Et j'aimerais bien aussi rendres ses classes un peu mieux lisibles.

Si c'est le cas, on peut instancier Negatif et utiliser les méthodes de la classe mère non ?

Oui, Negatif s'instancie et peux donc utiliser les méthodes de sa classe mère : Element.normaliser(Negatif("a"))

Mais je ne vois pas bien le rapport avec la manière de réduire toutes ses méthodes d'une lignes. Pourriez vous me donner plus de détails ?

2 Réponses

+2 votes
 
Meilleure réponse

Tu peux définir la méthode __getattr__ sur ta classe Negatif comme dans l'exemple ci-dessous. La méthode ne sera appelée que si l'attribut n'existe pas déjà, donc par exemple la méthode involuer sera appelée telle que définie explicitement.

class Negatif(Element):
    def __init__(self, element):
       assert isinstance(element, Element), "L'élément donné est mauvais : " + element
       Element.__init__(self)
       self.element = element

    def __getattr__(self, attr):
       return getattr(self.element, attr)

    def involuer(self):
       if type(self.element) is Negatif:
           return self.element.element
       else:
           return Negatif(self.element.involuer())
    def morganiser(self):
       element_morganise = self.element.morganiser()
       if type(self.element) is Or:
           return And(*[-x for x in element_morganise.elements]).morganiser()
       if type(self.element) is And:
           return Or(*[-x for x in element_morganise.elements]).morganiser()
       return element_morganise.associer()
    def est(self, other):
       if other.__class__ is Negatif:
           return True if self.element.est(other.element) else False
       else:
           return False
répondu 2-Avr par benjamin (366 points)
sélectionné 2-Avr par Andy
+2 votes

Je pense comme foxmask, après si tu veux récupérer les méthodes d'une autre classe qui n'est pas en héritage tu peux faire ça:

class Thief():
    def __init__(self, instance):
        for attribute in dir(instance):
            if not attribute.startswith("_"):
                attr = getattr(instance, attribute)
                if callable(attr):
                    setattr(self, attribute, attr)
répondu 25-Mar par ptank (306 points)

Non ce n'est pas vraiment ce que je veux faire. Je veux faciliter la manière de lire mon code en supprimant le maximum de ligne qui sont pratiquement semblable (Le fameux don't repeat yourself)

...