关于多父继承,当我调用super
。__init__
时,为什么不调用parent2的__init__
函数?感谢。
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()
输出
9
10
5
11
12
答案 0 :(得分:26)
如果您想使用super
中的child
来呼叫parent.__init__
和parent2._init__
,那么父__init__
}也必须呼叫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)
有关使用__init__
导致super
来电的顺序的详细信息,请参阅"Python super method and calling alternatives"。
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()
您可能想知道,“为什么要使用Base
?”。如果parent
和parent2
直接从object
继承,那么
super(parent2,self).__init__(x,y)
会致电object.__init__(x,y)
。由于TypeError
没有参数,因此提出了object.__init__()
。
要解决此问题,您可以创建一个类Base
,该类接受__init__
的参数,但不会将它们传递给object.__init__
。在parent
继承parent2
和Base
后,您可以避开TypeError
。
答案 1 :(得分:9)
由于parent
位于method resolution order (MRO)的下一个位置,因此它永远不会使用super()
来调用parent2
。
答案 2 :(得分:5)
见这个例子:
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())
这将输出:
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'>]
Python多重继承就像一个链,在Child
类mro
中,super
ParentA
类是ParentB
,所以你需要调用{{ 1}} super().__init__()
到初始ParentA
。
如果您将ParentB
更改为super().__init__('ParentA')
,则会破坏继承链,输出:
Base.__init__(self, 'ParentA')