super() 如何与多重继承一起工作?例如,给定:class First(object): def __init__(self): print \'first\'class Second(object): def __init__(self): ...
如何 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__
?我可以选择运行哪个吗?
有关 MRO 。
假设所有内容都来自 object
(如果不是,则您自己决定),Python 会根据您的类继承树计算方法解析顺序 (MRO)。MRO 满足 3 个属性:
如果不存在这样的顺序,Python 会出错。其内部工作原理是类祖先的 C3 线性化。在此处阅读所有内容: https://www.python.org/download/releases/2.3/mro/
调用某个方法时,将调用 MRO 中第一次出现的该方法。任何未实现该方法的类都会被跳过。 super
对该方法的任何调用都将调用 MRO 中下一次出现的该方法。因此,将类置于继承中的顺序以及将调用置于 super
方法中的位置都很重要。
注意,你可以使用该方法在python中查看MRO __mro__
。
下面所有的例子都有菱形的类继承,像这样:
Parent
/ \
/ \
Left Right
\ /
\ /
Child
MRO 是:
您可以通过调用来测试这一点 Child.__mro__
,它返回:
(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
super
first
class Parent(object):
def __init__(self):
super(Parent, self).__init__()
print("parent")
class Left(Parent):
def __init__(self):
super(Left, self).__init__()
print("left")
class Right(Parent):
def __init__(self):
super(Right, self).__init__()
print("right")
class Child(Left, Right):
def __init__(self):
super(Child, self).__init__()
print("child")
Child()
输出:
parent
right
left
child
super
都有
class Parent(object):
def __init__(self):
print("parent")
super(Parent, self).__init__()
class Left(Parent):
def __init__(self):
print("left")
super(Left, self).__init__()
class Right(Parent):
def __init__(self):
print("right")
super(Right, self).__init__()
class Child(Left, Right):
def __init__(self):
print("child")
super(Child, self).__init__()
Child()
输出:
child
left
right
parent
super
如果不是继承链中的所有类都调用,那么继承顺序就至关重要 super
。例如,如果 Left
永远不会调用 Right
和 Parent
上的方法
class Parent(object):
def __init__(self):
print("parent")
super(Parent, self).__init__()
class Left(Parent):
def __init__(self):
print("left")
class Right(Parent):
def __init__(self):
print("right")
super(Right, self).__init__()
class Child(Left, Right):
def __init__(self):
print("child")
super(Child, self).__init__()
Child()
输出:
child
left
或者,如果 Right
没有调用, super
, Parent
仍然会跳过:
class Parent(object):
def __init__(self):
print("parent")
super(Parent, self).__init__()
class Left(Parent):
def __init__(self):
print("left")
super(Left, self).__init__()
class Right(Parent):
def __init__(self):
print("right")
class Child(Left, Right):
def __init__(self):
print("child")
super(Child, self).__init__()
这里 Child()
输出:
child
left
right
如果要访问特定父类的方法,则应直接引用该类,而不是使用 super。Super 是遵循继承链,而不是获取特定类的方法。
以下是如何引用特定父母的方法:
class Parent(object):
def __init__(self):
super(Parent, self).__init__()
print("parent")
class Left(Parent):
def __init__(self):
super(Left, self).__init__()
print("left")
class Right(Parent):
def __init__(self):
super(Right, self).__init__()
print("right")
class Child(Left, Right):
def __init__(self):
Parent.__init__(self)
print("child")
在这种情况下, Child()
输出:
parent
child