super()内置函数
父类的构造函数必须手动调用, 调用方式有2种:
1. MyParentClass.__init__(xxx)
2. super(MyClass, self).__init__(xxx)
区别在于: 1比较直观, 在涉及多重继承时, 可以手动控制父类构造函数的调用顺序, 需要手动为每个父类调用一次构造函数; 2比较灵活, 动态查找父类, 在涉及多重继承时, 会自动调用各个直接父类的构造函数;
class A(object):
def __init__(self):
super(A, self).__init__()
print '__init__ A'
class B(A):
def __init__(self):
super(B, self).__init__()
print '__init__ B'
class C(B):
def __init__(self):
super(C, self).__init__()
print '__init__ C'
class AA(object):
def __init__(self):
super(AA, self).__init__()
print '__init__ AA'
class D(A, AA):
def __init__(self):
super(D, self).__init__()
print '__init__ D'
d = D()
# 自动调用所以直接父类的构造函数
#__init__ AA
#__init__ A
#__init__ D
class BB(A):
def __init__(self):
print '__init__ BB'
class CC(BB):
def __init__(self):
super(CC, self).__init__()
print '__init__ CC'
cc = CC()
# super()只会查找直接父类, 不会递归查找, 所以, 因为BB没有调动super, 所以A的构造函数就被调用
#__init__ BB
#__init__ CC
c = C()
# 当前类和父类都调用了super, 所以才能保证继承链上的所有构造函数都被调用
#__init__ A
#__init__ B
#__init__ C
三角继承
# 直接报错
class A:
pass
class B(A):
pass
class C(B, A):
pass
c = C()
#TypeError: Error when calling the metaclass bases
#Cannot create a consistent method resolution
#order (MRO) for bases B, A
报错原因
C继承A和B, 同时B也继承A, 对C来说, B和A是它的2个直接父类, 所以C在进行方法查找时, A和B具有相同的优先级, 但是这时候问题就来了:
1. 如果先从A再B, 那么B会覆盖A的方法(当然了, 这是我们所期望的, 因为B是A子类, 子类覆盖父类, 是理所当然的)
2. 如果先从B再A, 那么A会覆盖B的方法(出错了吧! 父类方法怎么可以覆盖子类方法呢!)
以上2种情况均可能出现, 这导致了方法解析顺序(MRO)不一致
解决方法
既然B继承A, 那么B已经包含了A的全部内容, 所以直接继承B就可以了, 没有必要继承A了:
class C(B):
pass
万事大吉!
菱形继承
class A(object):
def __init__(self):
super(A, self).__init__()
print '__init__ A'
class B(A):
def __init__(self):
super(B, self).__init__()
print '__init__ B'
class C(A):
def __init__(self):
super(C, self).__init__()
print '__init__ C'
class D(B, C):
def __init__(self):
super(D, self).__init__()
print '__init__ D'