1.super不是父类,而是继承顺序的下一个类
具体看这篇文章:https://rhettinger.wordpress.com/2011/05/26/super-considered-super/
通俗一点的解释如下:
class Base(object):
def __init__(self):
print 'Base create'
class childA(Base):
def __init__(self):
print 'enter A '
super(childA, self).__init__()
print 'leave A'
class childB(Base):
def __init__(self):
print 'enter B '
# Base.__init__(self)
super(childB, self).__init__()
print 'leave B'
class childC(childA, childB):
pass
c = childC()
print c.__class__.__mro__
输出结果如下:
enter A
enter B
Base create
leave B
leave A
(<class '__main__.childC'>, <class '__main__.childA'>, <class '__main__.childB'>, <class '__main__.Base'>, <type 'object'>)
想要知道为什么会有如上的执行结果就必须要理解 MRO
对于支持继承的编程语言来说,其方法(属性)可能定义在当前类,也可能来自于基类,所以在方法调用时就需要对当前类和基类进行搜索以确定方法所在的位置。而搜索的顺序就是所谓的「方法解析顺序」(Method Resolution Order,或MRO)
按照深度遍历,其顺序为 [C, A, Base, B, Base]
,重复类只保留最后一个,因此变为 [C, A, B, Base]
执行过程相当于:初始化childC()时,先会去调用childA,于是最先打印出‘enter A’,接着再调用A的构造方法中的 super(childA, self).__init__(), super(childA, self)返回当前类的继承顺序中childA后的一个类childB,于是有了‘enter B’,再调用 B 中的super(childB, self).__init__(),此时调用B的下一个顺序Base,于是有了输出‘Base create’;然后再输出 leave B,leave A (先入后出)
2. super()可以避免重复调用
class Base(object):
def __init__(self):
print 'Base create'
class childA(Base):
def __init__(self):
print 'enter A '
Base.__init__(self)
print 'leave A'
class childB(childA, Base):
def __init__(self):
childA.__init__(self)
Base.__init__(self)
b = childB()
Base 的 init被执行了两次
enter A
Base create
leave A
Base create
使用super()是可避免重复调用
class Base(object):
def __init__(self):
print 'Base create'
class childA(Base):
def __init__(self):
print 'enter A '
super(childA, self).__init__()
print 'leave A'
class childB(childA, Base):
def __init__(self):
super(childB, self).__init__()
b = childB()
print b.__class__.mro()
输出:
enter A
Base create
leave A
[<class '__main__.childB'>, <class '__main__.childA'>, <class '__main__.Base'>, <type 'object'>]
所以很多__init__()方法都会使用super()来调用,从而避免重复初始做强
Reference:
(1) https://www.zhihu.com/question/20040039
(2) http://python.jobbole.com/86993/