1

파이썬에서 다중 상속을 사용하면서 문제가 발생했는데 내가 잘못하고있는 것을 이해할 수 없습니다.파이썬 2.7 메소드 해상도 오버 라이드 주문

나는 세 클래스 A, B, C가 다음과 같이 정의되어있어 작동하지 않습니다.

class A(object): 
    def __init__(**kwargs): 
    . 
    . 

class B(object): 
    def __init__(**kwargs): 
    # prepare a dictionary "options" with the options used to call A 
    super(B,self).__init__(**options) 

    def coolmethod(x): 
     #some cool stuff 

A와 B의 경우 아무런 문제가 없습니다.

나는 A로부터 및 B 그래서 나는 coolmethod가 B에 정의 할 수있는 모두 상속 세 번째 클래스 C를 만들려하지만,

class C(A,B)가하는 정의하려고 A.에 정의 된 생성자를 사용하고 싶습니다 MRO가 정의되지 않았기 때문에 작동하지 않습니다.

그러나 class C(B,A)을 정의하는 것은 내가 아니라 B. 초기화보다 A.에게 초기화을 사용할 수 없습니다.

어떻게 문제를 해결할 수 있습니까?

답변

2

당신은 호출 할 수있는 .__ 초기화 __() 대신 직접 C에서 super()를 사용 : 여러 A로부터 상속과 다른 뭔가를 기대하는 경우가

class A(object): 
    def __init__(self, **kwargs): 
     super(A, self).__init__(**kwargs) 

을 사용할 수 있습니다

class C(B,A): 
    def __init__(self, **kwargs): 
     A.__init__(self, **kwargs) 
+0

감사합니다 .. 꽤 쉬웠습니다. 왜 클래스 선언의 순서가 중요 할 지 이해할 수 없습니다 .... – lucacerone

+1

주문에 대한 설명은 아래의 답변을 참조하십시오. –

2

. 이렇게하면 A.__init__이 항상 호출됩니다.

파이썬에서 메서드를 확인하는 방식 때문에 순서가 중요합니다. C가 (A, B)로부터 상속 받았다면, A와 B 모두에 존재하는 C에서 메소드를 호출하면 A에있는 메소드가 선택됩니다 (우선 순위가 있음). A 클래스에 super(A, self).method이라고 쓰면, method에 의해 제공되는 기능을 확장하고자 함을 의미합니다. 따라서 A와 B가 둘 다 확장되어 C가 둘 다 상속 된 경우 하나의 확장을 건너 뛰는 것이 이상 할 것입니다. 따라서 C.method으로 전화하면 A.method이 실행되고 super(A, self).method을 호출하면 B.method이 호출됩니다. 다른 말로하면, A가 메소드 확장 목적으로 B에서 상속받은 것과 같습니다. 이것은 C가 (B, A)에서 상속받을 때와 다릅니다.

모든 메소드와 마찬가지로 __init__의 첫 번째 인수는 항상 self이어야합니다.