python語言與C++有相似的類繼承,在類定義時,python中會自訂第一個self,類似C++中this指標,指向對象自身。
python簡單的類舉例:
>>> class hello(object):... def print_c():... print"hello world!">>> hello().print_c()hello world!
當然在實際中不可避免的需要類的繼承,子類繼承父類,正常如下:
>>> class child(hello):... def print_c(self):... hello().print_c()... >>> child().print_c()hello world!
在python中還提供了super()機制,例子如下:
>>> class hello(object):... def print_c(self):... print"hello world!"... >>> class child(hello):... def print_c(self):... super(child,self).print_c()... >>> child().print_c()hello world!
第一眼看過來是不是感覺一樣。
在python中引入super()的目的是保證相同的基類只初始化一次(注意:
1super ()機制是用來解決多重繼承的,對於直接調用父類名是沒有問題的,但在之後根據前人的經驗就是:要麼都用類名調用,要麼就全部用super(),不要混合的用,由此為人做事還是要專一的嘛O(∩_∩)O~
2 super()繼承只能用於新式類,用於經典類時就會報錯。
新式類:必須有繼承的類,如果無繼承的,則繼承object
經典類:沒有父類,如果此時調用super就會出現錯誤:『super() argument 1 must be type, not classobj)
好,再舉一個例子
class parent1(object): def __init__(self): print 'is parent1' print 'goes parent1'class parent2(object): def __init__(self): print 'is parent2' print 'goes parent2'class child1(parent1): def __init__(self): print'is child1' parent.__init__(self) print 'goes child1'class child2 (parent1) : def __init__(self): print 'is child2' parent.__init__(self) print 'goes child2'class child3(parent2): def __init__(self): print 'is child3' parent2.__init__(self) print 'goes child3'class grandson(child3,child2,child1): def __init__(self): print 'is grandson' child1.__init__(self) child2.__init__(self) child3.__init__(self) print'goes grandson'if __name__=='__main__': grandson()
is grandsonis child1is parent1goes parent1goes child1is child2is parent1goes parent1goes child2is child3is parent2goes parent2goes child3goes grandson
好了,在這兒發現什麼問題了沒有。對,基類parent1被多次執行,而有時我們只希望公用的類只被執行一次,那麼此時我們引入super()機制查看效果:
<span style="font-family: Arial, Helvetica, sans-serif;">class parent1(object):</span>
def __init__(self): super(parent1, self).__init__() print 'is parent1' print 'goes parent1'class parent2(object): def __init__(self): super(parent2, self).__init__() print 'is parent2' print 'goes parent2'class child1(parent1): def __init__(self): print'is child1' #parent1.__init__(self) super(child1, self).__init__() print 'goes child1'class child2 (parent1) : def __init__(self): print 'is child2' #parent1.__init__(self) super(child2, self).__init__() print 'goes child2'class child3(parent2): def __init__(self): print 'is child3' #parent2.__init__(self) super(child3, self).__init__() print 'goes child3'class grandson(child3,child2,child1): def __init__(self): print 'is grandson' #child1.__init__(self) #child2.__init__(self) #child3.__init__(self) super(grandson, self).__init__() print'goes grandson'if __name__=='__main__': grandson()
此時我們查看結果:
is grandsonis child3is child2is child1is parent1goes parent1goes child1goes child2is parent2goes parent2goes child3goes grandson
結果很明顯,公用基類parent1隻被執行一次。
grandson類的繼承體系如下圖所示:
object | / \ P1 P2 / \ | C1 C2 C3
所以對於類的繼承體系,我們可以看做一個圖,而每一個類看做一個節點,那麼super()機制的執行順序是按照圖的廣度優先搜尋演算法尋找super()的父類。
後續總結:
1. super()是一個類名而非函數,super(class, self)事實上調用了super類的初始化函數,產生了一個super對象;
2 super()機制必須要用新式類,否則會報錯;
3 super()或直接父類調用最好只選擇一種形式。