2017-10-07 48 views
2

在以下示例中,如果我將CL2中的super替換爲「in cl2 test cl5」中的self.test(),則會得到相同的輸出。超級如何做出任何改變。在python中是否超級冗餘?

class CL1(object): 
    def test(self): 
     print "test cl1" 

class CL2(CL1): 
    def abc(self): 

     print "in cl2" 
     super(CL2,self).test() 
     #self.test() 

class CL3(CL1): 
    def test(self): 
     print "test cl3" 

class CL5(CL1): 
    def test(self): 
     print "test cl5" 

class CL4(CL2,CL5,CL3): 
    def add(self): 
     print 'cl4' 

def main() 
    o=CL4() 
    o.abc() 
if __name__ == "__main__": 

    main() 
+0

有趣的問題。當對「對象」以外的任何其他對象進行子類化時,這是絕對必要的。 –

+0

'super'被誤稱;它不一定是指使用它的類的(單個)靜態定義的父類。 – chepner

回答

2

如果你不使用super,那麼類CL2內,它隱含的調用它的父(CL1)的test()方法。

但是,當類CL2也定義了一個名爲test()(在OOP中稱爲方法覆蓋)的方法時,會出現模糊問題。缺省值是使用當前類的test()方法,但是如果您想調用父類的方法,那麼您需要使用super明確調用其超類的test()方法。

考慮這個例子:

class CL1(object): 
    def test(self): 
     print "test CL1" 

class CL2(CL1): 
    def test(self): 
     print "test CL2" 

    def abc(self): 

     print "in CL2" 
     super(CL2,self).test() 
     self.test() 

o=CL2() 
o.abc() 

將輸出:

in CL2 
test CL1 
test CL2 
+0

這裏你不需要'超級'你可以明確地簡單地調用'CL1.test(self)'。 – chepner

+0

是的。謝謝chepner。我知道。但是,如果CL1類的名字改變了怎麼辦? –

+0

如果更改名稱,也可以更改與其關聯的代碼。如果你使用'super',它更加*方便*,但它不是必須的,這並不是爲什麼'super'被添加到語言中。 – chepner

-2

super不只是離開的基類的名字給你的孩子,類方法便利;它被設計爲合作繼承,其中正確設計的類將根據C3線性化算法以正確的順序調用覆蓋方法。

super不一定是指您定義的類的靜態聲明父對象。請看下面的代碼:

class A: 
    def foo(self): 
     print("A.foo") 

class B(A): 
    def foo(self): 
     print("B before super") 
     super().foo() 
     print("B.foo") 

class C(A): 
    def foo(self): 
     print("C before super") 
     super().foo() 
     print("C.foo") 

class D(B, C): 
    def foo(self): 
     print("D before super") 
     super().foo() 
     print("D.foo") 

print(D.__mro__) 
d = D() 
d.foo() 

呼叫super().foo()B.foo不調用A.foo當您運行;它運行的是C.foo,因爲C緊接在B之後,在類別D的方法解析順序(MRO)中。

如果你不與B.foo總是調用A.foo馬上,不管self類型的確定,不使用super。通過使用super,您同意它旨在支持的語義,並應該將該方法記錄爲使用super。否則,請改爲使用A.foo(self),並使用super記錄您是而不是的事實。