2017-10-07 1 views
2

다음 예제에서는 CL2의 super를 "cl2 test cl5"의 self.test()로 대체하면 동일한 출력을 얻습니다. 수퍼는 정확히 어떤 차이를 만듭니다.파이썬에서 슈퍼가 중복됩니까?

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

그런 다음 클래스 CL2 내부는 암시 적으로 부모 (CL1)의 test() 메소드를 호출, super을 사용하지 않는 경우.

그러나 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

여기서'super'는 필요 없습니다; CL1.test (self)를 명시 적으로 쉽게 호출 할 수있다. – chepner

+0

예. 너 chepner 고마워. 알아. 그러나 클래스 'CL1'의 이름이 변경되면 어떻게 될까요? –

+0

이름을 변경하면 해당 이름도 변경할 수 있습니다. 'super'를 사용한다면 더 편리합니다 * 그러나 * 반드시 필요하지는 않습니다. 왜냐하면'super'가 언어에 추가 된 이유가 아닙니다. – chepner

-2

super 자녀-클래스 메소드에서 기본 클래스의 이름을 떠나는 단지 편의 아니다; cooperative 상속을 위해 설계되었으며, 적절하게 설계된 클래스는 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() 

당신이 d.foo()을 실행할 때 B.foo 내부 super().foo()A.foo를 호출하지 않습니다 호출을; CD의 방법 결정 순서 (MRO)로 B 바로 뒤에 오기 때문에 C.foo을 대신 실행합니다. 당신이 B.foo하지 항상에 관계없이 self의 종류, 즉시 A.foo 전화로 확인을하지 않은 경우

super를 사용하지 마십시오. super을 사용하면 지원하도록 설계된 의미 체계에 동의하고 super을 사용하여 메서드를 문서화해야합니다. 그렇지 않은 경우 A.foo(self)을 대신 사용하고 이 아닌super을 사용한다는 사실을 문서화하십시오.

관련 문제