multiple multi herencia python oop inheritance init super

herencia multiple python



Python multi-herencia,__init__ (3)

Mira este ejemplo:

class Base(object): def __init__(self, c): print(''Base called by {0}''.format(c)) super().__init__() class ParentA(Base): def __init__(self, c): print(''ParentA called by {0}''.format(c)) super().__init__(''ParentA'') class ParentB(Base): def __init__(self, c): print(''ParentB called by {0}''.format(c)) super().__init__(''ParentB'') class Child(ParentA, ParentB): def __init__(self, c): print(''Child called by {0}''.format(c)) super().__init__(''Child'') Child(''Construct'') print(Child.mro())

Esto dará como resultado:

Child called by Construct ParentA called by Child ParentB called by ParentA Base called by ParentB [<class ''__main__.Child''>, <class ''__main__.ParentA''>, <class ''__main__.ParentB''>, <class ''__main__.Base''>, <class ''object''>]

La herencia múltiple de Python es como una cadena, en Child clase Child mro , la ParentA de ParentA es ParentB , por lo que necesita llamar a super().__init__() en ParentA para ParentB .

Si cambia super().__init__(''ParentA'') a Base.__init__(self, ''ParentA'') , esto romperá la cadena de herencia, y generará:

Child called by Construct ParentA called by Child Base called by ParentA [<class ''__main__.Child''>, <class ''__main__.ParentA''>, <class ''__main__.ParentB''>, <class ''__main__.Base''>, <class ''object''>]

Más información acerca de MRO

En cuanto a la herencia de padres múltiples, cuando llamo al super . __init__ , ¿por qué no se llama a la función __init__ de __init__ ? Gracias.

class parent(object): var1=1 var2=2 def __init__(self,x=1,y=2): self.var1=x self.var2=y class parent2(object): var4=11 var5=12 def __init__(self,x=3,y=4): self.var4=x self.var5=y def parprint(self): print self.var4 print self.var5 class child(parent, parent2): var3=5 def __init__(self,x,y): super(child, self).__init__(x,y) childobject = child(9,10) print childobject.var1 print childobject.var2 print childobject.var3 childobject.parprint()

La salida es

9 10 5 11 12



Si desea utilizar super en child para llamar al parent.__init__ y parent2._init__ , ambos padres __init__ s también deben llamar a super :

class parent(Base): def __init__(self,x=1,y=2): super(parent,self).__init__(x,y) class parent2(Base): def __init__(self,x=3,y=4): super(parent2,self).__init__(x,y)

Consulte "Super método de Python y alternativas de llamada" para obtener más detalles sobre la secuencia de llamadas a __init__ causadas por el uso de super .

class Base(object): def __init__(self,*args): pass class parent(Base): var1=1 var2=2 def __init__(self,x=1,y=2): super(parent,self).__init__(x,y) self.var1=x self.var2=y class parent2(Base): var4=11 var5=12 def __init__(self,x=3,y=4): super(parent2,self).__init__(x,y) self.var4=x self.var5=y def parprint(self): print self.var4 print self.var5 class child(parent, parent2): var3=5 def __init__(self,x,y): super(child, self).__init__(x,y) childobject = child(9,10) print childobject.var1 print childobject.var2 print childobject.var3 childobject.parprint()

Es posible que se pregunte: "¿Por qué usar Base ?". Si parent y parent2 han heredado directamente del object , entonces super(parent2,self).__init__(x,y) llamaría al object.__init__(x,y) . Eso genera un TypeError ya que el object.__init__() no toma parámetros.

Para solucionar este problema, puede crear una Base clase que acepte argumentos para __init__ pero no los pase al object.__init__ . Con parent y parent2 heredando de Base , evita el TypeError .