Note: super() only works for new-style classes.
super() 函数的一个常见用法是在 __init__() 方法中确保父类被正确的初始化了
super() 函数是子类用于调用父类(超类)的一个方法。
super 是用来解决多重继承问题的,直接用类名调用父类(Base.__init__(self))方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。
MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表。
假如说在父类中实现了一个方法,你想在子类中使用父类的这个方法并且做一定扩展但是又不想完全重写,并且这个场景中的继承属于多继承,那么super()就出场了,可以实现方法的增量修改。
python2:
super(CurrentClass, self).method(arg)
python3:
super().method(arg)
class BasicClassPeople(object):
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def short_introduction(self):
print 'My name is {}, a {}, this year I am {} years old'.format(self.name,self.gender,self.age)
class ExtenClassOne(BasicClassPeople):
def __init__(self,name,age,gender,job):
super(ExtenClassOne, self).__init__(name,gender,age)
self.job = job
def short_introduction(self):
print 'My name is {}, a {}, this year I am {} years old, my job is {}'.format(self.name, self.gender, self.age,self.job)
在上边的程序中ExtenClassOne继承自BasicClassPeople,但是它想在初始化的时候为类新增加一个属性,如果不使用super的话我们就只能重写初始化函数了,但是使用了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__')
运行这段代码就会发现 Base.__init__() 被调用两次,如下所示:
>>> c = C()
Base.__init__
A.__init__
Base.__init__
B.__init__
C.__init__
>>>
使用super()之后
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__() # Only one call to super() here
print('C.__init__')
运行结果:
发现每个__init__() 方法只会被调用一次了:
>>> c = C()
Base.__init__
B.__init__
A.__init__
C.__init__
>>>
http://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p07_calling_method_on_parent_class.html