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
Porque el parent es el siguiente en la orden de resolución de métodos (MRO) , y nunca usa super() para llamar a parent2 .
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 .