总体
假设所有内容都源自object(如果不是,则您只能靠自己),Python 会根据您的类继承树计算方法解析顺序 (MRO)。 MRO 满足 3 个属性:
- 一个班级的孩子比他们的父母更早
- 左父母先于右父母
- 一个类在 MRO 中只出现一次
如果不存在这样的排序,Python 会出错。其内部工作是类祖先的 C3 线性化。在此处阅读所有相关信息:https://www.python.org/download/releases/2.3/mro/
因此,在下面的两个示例中,它都是:
- 孩子
- 左
- 对
- 父母
调用方法时,MRO 中该方法的第一次出现就是被调用的方法。任何未实现该方法的类都将被跳过。在该方法中对super 的任何调用都将调用该方法在 MRO 中的下一次出现。因此,在继承中放置类的顺序以及在方法中调用super 的位置都很重要。
请注意,您可以使用__mro__ 方法在python 中查看MRO。 Child.__mro__ 在以下任何示例中都会返回:
(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
示例
以下所有示例都具有如下类的菱形继承:
Parent
/ \
/ \
Left Right
\ /
\ /
Child
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):
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 没有调用super,那么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