Question

J'ai hérité d'une classe et écrasé une méthode qui a également hérité d'une classe de base.Mais le truc, c'est que le milieu de méthode crée une exception que je voudrais contourner par l'appel de la première méthode déclarée.Est-il un moyen de spécifier à l' mro qui ignore les appels deuxième?

Un exemple pourrait être:

class Base(object):
     def __init__(self):
         res = "Want this"
         print res

class BaseA(Base):
      def __init__(self):
          res = super(BaseA, self).__init__()
          res = "Not this"
          print res

class BaseB(BaseA):
      def __init__(self):
          res = super(BaseB, self).__init()
          #At this poing res is "Not this"
          #The desire is that it would be "Want this"
          print res

Merci beaucoup

PD:Quelque chose comme la classe, la BaseB(Base, BaseA) pourrait fonctionner?

Était-ce utile?

La solution

Normalement vous auriez corrigé cette méthode à la place.

Toutefois, le premier argument de super() est l'endroit pour commencer la recherche de la méthode suivante à partir de.Normalement, ce serait la classe en cours, mais vous pouvez également passer dans la classe de base:

class BaseB(BaseA):
    def __init__(self):
        res = super(BaseA, self).__init__()

Ici, super() prend la MRE de type(self), trouve BaseA dans ce MRO, et cherche la prochaine classe de mise en œuvre de __init__.

Une autre manière de contourner la problématique __init__ méthode est à juste appeler la méthode sur unbound Base directement:

class BaseB(BaseA):
    def __init__(self):
        res = Base.__init__(self)

ignorant tout MRO recherches entièrement.

Autres conseils

La bonne Façon de résoudre ce problème est de créer une nouvelle hiérarchie de classe qui remplace la délinquance de la méthode avec une meilleure mise en œuvre.Si vous insistez sur la hackery bien, c'est peut être ce que vous voulez:

class BaseB(BaseA):
      def __init__(self):
          res = super(BaseA, self).__init()
          #At this poing res is "Not this"
          #The desire is that it would be "Want this"
          print res

Notez que je demande pour la super mise en œuvre à l'égard de BaseA, ce qui signifie que le BaseA mise en œuvre n'est jamais utilisé.


Cependant, ce peut faire la Mauvaise Chose lorsque diamant héritage est impliqué.Considérer:

class Base(object):
    def __init__(self):
        print 'initing Base'

class BaseA(Base):
    def __init__(self):
        print 'initing BaseA'
        res = super(BaseA, self).__init__()

class BaseB(BaseA):
    def __init__(self):
        print 'initing BaseB'
        res = super(BaseA, self).__init__()

class BaseC(BaseA):
    def __init__(self):
        print 'initing BaseC'
        res = super(BaseC, self).__init__()

class BaseD(BaseB, BaseC):
    def __init__(self):
        print 'initing BaseD'
        res = super(BaseD, self).__init__()

print BaseD()

La sortie est :

initing BaseD
initing BaseB
initing Base
<__main__.BaseD object at 0x7f1e693a0110>

BaseC a été ignoré, même si ce n'est pas ce que nous voulions.C'est parce que BaseC entre BaseB et BaseA dans la méthode de résolution de l'ordre, de sorte que lorsque nous avons sauté de BaseB pour BaseA nous avons négligé par inadvertance BaseC.

>>> print [cls.__name__ for cls in BaseD.mro()]
['BaseD', 'BaseB', 'BaseC', 'BaseA', 'Base', 'object']

Comment combat juste

Base.__init__(self)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top