測試了一個下午,上網找了很久,真的這個差別太讓我郁悶了!最郁悶的是python官網文檔沒有這麼詳細的差別介紹
Python類分為兩種,一種叫經典類,一種叫新式類。兩種都支援多繼承。
情形一:
B繼承于A,C繼承于A和B
# 經典類
class A():
def __init__(self):
print 'A'
class B(A):
def __init__(self):
A.__init__(self)
print 'B'
class C(B, A):
def __init__(self):
A.__init__(self)
B.__init__(self)
print 'C'
C需要調用父類的init()函數時,前者會導緻父類A的init()函數被調用2次,效率不高,而且不符合DRY原則,是以有了下面的新方法
# 新式類
class A(object):
def __init__(self):
print 'A'
class B(A):
def __init__(self):
super(B, self).__init__()
print 'B'
class C(B, A):
def __init__(self):
super(C, self).__init__()
print 'C'
采用super()方式時,會自動找到第一個多繼承中的第一個父類,那就不用調用兩次了
情形二:
B繼承于A,D繼承于C和B
class A(object):
def __init__(self):
print 'A'
class B(A):
def __init__(self):
super(B, self).__init__()
print 'B'
class C(object):
def __init__(self):
print 'C'
class D(B, C):
def __init__(self):
super(B, self).__init__()
C.__init__(self)
print 'B'
兩個類的初始化不同,而隻有B需要追溯父類使用super(),另一個就要沿用舊方法才能初始化
情形三:
菱形繼承,B繼承于A,C繼承于A,D繼承B和C
class A():
def __init__(self):
print('enter A')
print('leave A')
class B(A):
def __init__(self):
print('enter B')
super().__init__()
print('leave B')
class C(A):
def __init__(self):
print('enter C')
super().__init__()
print('leave C')
class D(B, C):
def __init__(self):
print('enter D')
super().__init__()
print('leave D')
d = D()
使用 super() 可以很好地避免構造函數被調用兩次的問題
##實驗測試了情形一和情形二,如有修改或錯誤地方,還望大蝦指正
Reference: