Pergunta

Eu tenho um herdado de uma classe e sobrescrever um método que também é herdado de uma classe base.Mas a coisa é que o meio, o método cria uma exceção que eu gostaria de ignorar chamando o primeiro método declarado.Existe uma maneira de especificar para o mro que ignora a segunda chama?

Um exemplo poderia ser:

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

Muito obrigado

PD:Algo como classe BaseB(Base, BaseA) poderia trabalhar?

Foi útil?

Solução

Normalmente você gostaria de corrigir esse método em vez disso.

No entanto, o primeiro argumento para super() é o lugar para começar a procurar o método seguinte a partir de.Normalmente, seria a classe atual, mas você também pode passar na classe base:

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

Aqui, super() leva a MRO de type(self), encontra BaseA no que MRO, e olha para a próxima classe de execução __init__.

Outra maneira de ignorar a problemática __init__ o método é apenas para chamar independente do método de Base diretamente:

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

ignorando qualquer MRO pesquisas inteiramente.

Outras dicas

O Caminho Certo para corrigir esse problema é criar uma nova hierarquia de classes que substitui o método incorreto com uma melhor implementação.Se você insistir em hackery porém, isso pode ser o que você deseja:

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

Note que estou pedindo para o super implementação com relação ao BaseA, o que significa que o BaseA implementação nunca é usado.


No entanto, este pode fazer a Coisa Errada quando diamante herança está envolvido.Considere:

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()

A saída é :

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

BaseC foi ignorado, apesar de que não é o que queríamos.Isso é porque BaseC veio entre BaseB e BaseA no método de resolução de ordem, por isso, quando deixamos de lado a partir de BaseB para BaseA inadvertidamente, negligenciadas BaseC.

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

Como bout apenas

Base.__init__(self)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top