2009-05-24 7 views
242

이것을 고려하십시오 - 기본 클래스 A, B를 상속 한 클래스 C, B를 상속 한 클래스 C 생성자에서 부모 클래스 생성자를 호출하는 일반적인 방법은 무엇입니까? 그래도 여전히 너무 애매한 경우 여기에 몇 가지 코드가 있습니다.파이썬에서 체인 호출 상위 생성자

class A(object): 
    def __init__(self): 
     print "Constructor A was called" 

class B(A): 
    def __init__(self): 
     super(B,self).__init__() 
     print "Constructor B was called" 

class C(B): 
    def __init__(self): 
     super(C,self).__init__() 
     print "Constructor C was called" 

c = C() 

지금 내가하는 방법입니다. 그러나 여전히 너무 비 범용적인 것으로 보입니다. 올바른 유형을 수동으로 전달해야합니다.

이제 super()에 대한 첫 번째 인수로 self.__class__을 사용해 보았습니다.하지만 분명히 작동하지 않습니다. C의 생성자에 넣으면 B의 생성자가 호출됩니다. B에서 똑같이하면 "self"는 여전히 C의 인스턴스를 가리 키므로 결국 B의 생성자를 다시 호출하게됩니다 (이 작업은 무한 재귀에서 끝납니다).

다이아몬드 상속을 지금 당장 생각할 필요가 없습니다.이 특정 문제를 해결하는 데 관심이 있습니다.

+0

을 "하지만 여전히 조금 너무 제네릭이 아닌 것을 - 당신 손으로 올바른 유형을 통과해야합니다. " 클래스 이름을 super()에 전달하고 있습니다. 수퍼 클래스 또는 다른 것을 알 필요가 없습니다. 이것은 비 제너릭 (non-generic) 인 방법은 무엇입니까? 어떤 문제가 발생합니까? 이 부분이 깨지는 사례를 줄 수 있습니까? –

+3

충분한 경우이 질문에 답변 할 준비가되지 않았습니다. 하지만 어쨌든 클래스 이름이 변경되면 어떻게 될까요? 이런 종류의 체인을 자동화하는 데코레이터 함수를 작성하고자한다면 어떻게해야할까요? 이제는 이것이 불가능하다는 것을 알았지 만 질문을 할 때 나는 그것을 알지 못했습니다. – shylent

답변

151

실제로하는 방법 (Python 2.x의 경우)이 좋습니다.

클래스가 명시 적으로 super에 전달되는지 여부는 기능보다는 스타일에 달려 있습니다. 클래스를 super에 전달하는 것은 Python의 철학 인 "explicit is implicit"에 적합합니다.

super().__init__(args) 
+3

어느 대답을 받아 들일지 결정하기가 힘들었지 만, 제가 사용하고있는 파이썬 버전과 관련이 있기 때문에 받아 들일 것입니다. – shylent

+9

Python 2.6에서는이 메소드를 사용하여'TypeError : super() 인수 1이 형식이어야하고 classobj가 아니어야합니다. '라는 메시지가 표시됩니다. 내가 놓친 게 있니? – Leopd

+12

@Leopd :'super()'는 새로운 스타일의 클래스에서만 작동합니다. 즉,'object'에서 상속해야합니다. –

159

파이썬 3는 다음과 같이 사용할 수있는 개선 된 슈퍼() 포함

class A(object): 

    def __init__(self): 
     print "Constructor A was called" 

class B(A): 

    def __init__(self): 
     A.__init__(self) 
     # A.__init__(self,<parameters>) if you want to call with parameters 
     print "Constructor B was called" 

class C(B): 

    def __init__(self): 
     # A.__init__(self) # if you want to call most super class... 
     B.__init__(self) 
     print "Constructor C was called" 
+0

을 참조하십시오. super는 호출 할 상위 클래스를 식별합니까? – Kracekumar

+2

@kracekumar 그것은 'MyClassName.mro()'를 호출하여 찾을 수있는 클래스의'Method Resolution Order (MRO) '에 의해 결정됩니다. 나는 잘못되었을 수도 있지만 처음에 지정된 부모가'__init__'가 호출 될 것이라고 믿습니다. –

+0

@ ironfroggy, 당신은이 질문에 대한 향상된 슈퍼 도움말을 어떻게 자세하게 설명해 주시겠습니까? 방금이 낡은 실을 발견했고 똑같은 질문을했습니다. 또한이 질문이 처음으로 제기 된 이후로 Python 2.x에서 개선 된 점이 있습니까? –

22

당신은 간단하게 작성할 수 있습니다 :