2013-01-04 3 views
2

Python webpage에있는 문서에서 파이썬의 클래식 클래스에 대한 메서드 확인 순서는 깊이 우선 왼쪽에서 오른쪽 탐색으로 설명됩니다. 내가 예상하는 동안Python에서 다중 상속을 사용하는 MRO

Initialized C 
Initialized D 

: 나는 개체 D의 인스턴스를 만들 때

class A(object): 
def __init__(self): 
    print "Initialized A" 

class B(A): 
    def test(): 
     print "Initialized B" 

class C(A): 
    def __init__(self): 
     print "Initialized C" 

class D(B, C): 
    def __init__(self): 
     super(D, self).__init__() 
     print "Initialized D" 

가 :

D() 

을 나는 결과를 얻을 나는이 코드 조각이 테스트를하려고 MRO가 깊이 우선이므로 "초기화 된 A", "초기화 된 D"를 인쇄합니다. B에서 초기화가 먼저 검색됩니다 (해당되는 경우). 계층에서 더 깊어 져야하며 기본의 함수를 찾아야합니다 뚜껑 B의 s (즉, 에이). 누군가가 나에게 A 대신에 C의 init 함수를 얻는 이유를 설명해 줄 수 있습니까? D

답변

4

클래스는 object에서 상속되므로 고전적인 클래스는 아닙니다. 그것은 새로운 스타일의 클래스입니다. (새 스타일 클래스에서 상속 한 클래스도 새 스타일 클래스입니다.)

어쨌든 super은 클래식 클래스에서는 사용할 수 없습니다. 당신이 인용하는 "깊이 우선 첫번째 왼쪽에서 오른쪽으로"규칙은 인스턴스에서 직접 정의되지 않은 속성에 액세스하려고 할 때 순서 기반 클래스에 대한 속성 조회 규칙 만 검색합니다. 클래식 클래스는 MRO를 제공하지 않으므로 명시 적으로 특정 수퍼 클래스를 참조하지 않고도 속성의 "수퍼 클래스 값"에 액세스 할 수있는 방법이 없습니다.

4

MRO는 다음과 같습니다

print(D.mro()) 
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>] 

그래서

super(D, self).__init__() 

Dself.__class__.mro()에서 첫 번째 클래스에 __init__ 방법을 찾습니다. B에는 __init__이 없으므로 메서드를 C에서 찾습니다. 그것은 C.__init__을 발견, 따라서

super(D, self).__init__() 

C.__init__(self)를 호출합니다.

supergetattr(B, __init__)에 액세스하려고하지 않습니다. 오히려 B.__dict__'__init__'을 찾고 있습니다.