2017-10-07 64 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记录您是而不是的事实。