class Base():
def __init__(self):
print("Base")
class First(Base):
def __init__(self):
super().__init__()
print("first")
class Second(Base):
def __init__(self):
print("second")
class Third(First,Second):
def __init__(self):
super().__init__()
print("third")
Third()
为何输出结果为
second
first
third
为什么 First 中 super().init() 没有被调用呢
如果代码改为
class Base():
def __init__(self):
print("Base")
class First(Base):
def __init__(self):
super().__init__()
print("first")
class Second(Base):
def __init__(self):
super().__init__()
print("second")
class Third(First,Second):
def __init__(self):
super().__init__()
print("third")
Third()
则输出结果为
Base
second
first
third
1
gwy15 2020-07-17 21:53:20 +08:00
调用 super() 的时候实际上会跟随 MRO 进行链式调用,在这个例子里面,调用链是(从左到右宽度优先搜索)
`Third` -> `First` -> `Second` -> `Base` -> `object` 可以用 `Third.mro()` 查看。 因此,在调用的时候,Third.__init__ 里面 super().__init__() 实际调用的是 Second.__init__(self),而 Second.__init__ 里面没有继续调用 super,所以 Base 的 __init__ 没有调用。 |
2
gwy15 2020-07-17 21:57:45 +08:00
上面有点笔误
Third -> First -> Second -/-> Base >>> second >>> first >>> third |
3
marquina 2020-07-17 22:01:29 +08:00
@gwy15 更准确地说,Third.__init__里的 super().__init__()调用的是 First.__init__,First.__init__里的 super().__init__调用的是 Second.__init__。
|
5
doraemon1293 OP 感谢回答
两种情况 打印 Third.__mro__ 结果都是 (<class '__main__.Third'>, <class '__main__.First'>, <class '__main__.Second'>, <class '__main__.Base'>, <class 'object'>) 多重继承 super 不是从左到右查找吗 为什么会调用 Second.__init__(self) 我把打印的代码改成标注开始和结束 ``` class Base(): def __init__(self): print("Base") class First(Base): def __init__(self): print("first start") super().__init__() print("first end") class Second(Base): def __init__(self): print("second start") # super().__init__() print("second end") class Third(First,Second): def __init__(self): super().__init__() print("third") print(Third.__mro__) Third() ``` 结果如下 first start second start second end first end third 为什么 first 先被调用 然而 first 里的 super().__init__()没有任何效果呢? |
6
doraemon1293 OP 刚看到你的更正 请忽略我上面的回复
为什么 First.__init__里的 super().__init__调用的是 Second.__init__。 First 的 super 不应该调用他的父类 Base 吗? |
7
gwy15 2020-07-17 22:07:34 +08:00
@doraemon1293 super 是根据 MRO 链走的,不是“父类”。
|
8
doraemon1293 OP @gwy15
明白了 一直以为 super 是调用父类 多谢解答 |
9
oahebky 2020-07-17 22:22:45 +08:00 via Android
这是个新式类+钻石继承的问题。
没有什么特别的东西,就是“规定”。 具体参见 《 learning Python 》(有中文版)类的高级主题部分 - 第 31 章。 自认为没有能力解释得比书上更好,所以不多做解释,仅指路。 |
10
HFcbyqP0iVO5KM05 2020-07-18 10:47:41 +08:00 via Android 1
不如亲自看看 Python 之父当时解决 MRO 的思路:
http://python-history.blogspot.com/2010/06/method-resolution-order.html?m=1 |