python中的super()函数讨论
class Base:
def __init__(self):
print('Base.__init')
class A(Base):
def __init__(self):
Base.__init__(self)
print('A.__init')
class B(Base):
def __init__(self):
Base.__init__(self)
print('B.__init')
class C(A,B):
def __init__(self):
A.__init__(self)
B.__init__(self)
print('C._init')
c=C()
#输入如下:
Base.__init
A.__init
Base.__init
B.__init
C._init
可以看到Base.init被调用了两次,当使用super()发现每个__init()只调用了一次
class Base:
def __init__(self):
print('Base.__init')
class A(Base):
def __init__(self):
super().__init__()
print('A.__init')
class B(Base):
def __init__(self):
super().__init__()
print('B.__init')
class C(A,B):
def __init__(self):
super().__init__()
print('C._init')
c=C()
#输出如下:
Base.__init
B.__init
A.__init
C._init
这里我们要知道 python是如何实现继承的,print(C.mro)
(<class ‘main.C’>, <class ‘main.A’>, <class ‘main.B’>, <class ‘main.Base’>, <class ‘object’>)
可以看到顺序如下C-A-B-Base-ojbect
先检查子类,有多个父类时,按顺序依次检查。当使用super()时,python会从mro中的上一个类开始搜索。只要每一个重新定义过的方法,即覆盖方法。都使用了super(),并且调用 了它一次,那么控制流历边整个mro列表,并且让每个方法只会被调用 一次。这就是为什么 Base.__init只被调用一次。
然后再看一个例子
class A():
def prt(self):
print('A.print')
super().prt()
a=A()
a.prt()
#这个程序会报错 super()没有prt
但是多重继承我们看会发生什么
class A():
def prt(self):
print('A.print')
super().prt()
class B():
def prt(self):
print('B.print')
class C(A,B):
pass
c=C()
c.prt()
#输出结果入下
A.print
B.print
这里发现A中使用的super().prt()调用了B类的prt()方法。这一切都可以通过C.__mrc__来解释
(<class ‘main.C’>, <class ‘main.A’>, <class ‘main.B’>, <class ‘object’>)
可以看到 C->A->B->object
Python3.x 和 Python2.x 的一个区别是: Python 3 可以使用直接使用 super().xxx 代替 super(Class, self).xxx