super()如何处理多重继承?例如,给定:
class First(object):
def __init__(self):
print "first"
class Second(object):
def __init__(self):
print "second"
class Third(First, Second):
def __init__(self):
super(Third, self).__init__()
print "that's it"
Third的哪个父方法执行super()。__init__ refer to?我可以选择哪些运行吗?
我知道这与方法解析顺序(MRO)有关。
在python 3.5+中,继承看起来是可预测的,对我来说非常好。
请看下面的代码:
class Base(object):
def foo(self):
print(" Base(): entering")
print(" Base(): exiting")
class First(Base):
def foo(self):
print(" First(): entering Will call Second now")
super().foo()
print(" First(): exiting")
class Second(Base):
def foo(self):
print(" Second(): entering")
super().foo()
print(" Second(): exiting")
class Third(First, Second):
def foo(self):
print(" Third(): entering")
super().foo()
print(" Third(): exiting")
class Fourth(Third):
def foo(self):
print("Fourth(): entering")
super().foo()
print("Fourth(): exiting")
Fourth().foo()
print(Fourth.__mro__)
输出:
Fourth(): entering
Third(): entering
First(): entering Will call Second now
Second(): entering
Base(): entering
Base(): exiting
Second(): exiting
First(): exiting
Third(): exiting
Fourth(): exiting
(<class '__main__.Fourth'>, <class '__main__.Third'>, <class '__main__.First'>, <class '__main__.Second'>, <class '__main__.Base'>, <class 'object'>)
正如你所看到的,它对每个继承链调用foo一次,其顺序与继承链的顺序相同。你可以通过调用.mro来获得订单:
Fourth -> Third -> First -> Second -> Base ->对象
class First(object):
def __init__(self, a):
print "first", a
super(First, self).__init__(20)
class Second(object):
def __init__(self, a):
print "second", a
super(Second, self).__init__()
class Third(First, Second):
def __init__(self):
super(Third, self).__init__(10)
print "that's it"
t = Third()
输出是
first 10
second 20
that's it
调用Third()定位在Third中定义的init。在这个例程中调用super调用First中定义的init。MRO =(一、二)。
现在在First中定义的init中调用super将继续搜索MRO并找到Second中定义的init,并且任何对super的调用都将命中默认对象init。我希望这个例子能够阐明这个概念。
如果你不在第一分局给管理员打电话。链条停止,您将得到以下输出。
first 10
that's it
在这种情况下,你试图继承的每个类都有自己的init位置参数,只需调用每个类自己的init方法,如果试图继承多个对象,则不要使用super。
class A():
def __init__(self, x):
self.x = x
class B():
def __init__(self, y, z):
self.y = y
self.z = z
class C(A, B):
def __init__(self, x, y, z):
A.__init__(self, x)
B.__init__(self, y, z)
>>> c = C(1,2,3)
>>>c.x, c.y, c.z
(1, 2, 3)
你的代码和其他答案都是错误的。它们缺少前两个类中的super()调用,这是合作子类化工作所必需的。更好的是:
class First(object):
def __init__(self):
super(First, self).__init__()
print("first")
class Second(object):
def __init__(self):
super(Second, self).__init__()
print("second")
class Third(First, Second):
def __init__(self):
super(Third, self).__init__()
print("third")
输出:
>>> Third()
second
first
third
super()调用在每一步都在MRO中查找下一个方法,这就是为什么First和Second也必须拥有它,否则执行将在Second.__init__()结束时停止。
如果在First和Second中没有super()调用,输出就会丢失Second:
>>> Third()
first
third