“mro ()”는 무엇을합니까?


답변:


211

을 따라서...:

>>> class A(object): pass
... 
>>> A.__mro__
(<class '__main__.A'>, <type 'object'>)
>>> class B(A): pass
... 
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
>>> class C(A): pass
... 
>>> C.__mro__
(<class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
>>> 

단일 상속 __mro__이있는 한, 클래스,베이스,베이스베이스 등의 튜플 object일뿐입니다 (물론 새로운 스타일 클래스에서만 작동합니다).

이제 다중 상속으로 ... :

>>> class D(B, C): pass
... 
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)

... 또한에서 __mro__클래스가 중복되지 않고 조상 뒤에 오는 클래스가 없다는 것을 확신 할 수 있습니다 . 동일한 수준의 다중 상속 (이 예에서 B 및 C와 같은)에서 처음 입력되는 클래스가 __mro__왼쪽에서 오른쪽으로.

메서드뿐만 아니라 클래스의 인스턴스에서 얻는 모든 속성은 개념적으로를 따라 조회 __mro__되므로 조상 중 두 개 이상의 클래스가 해당 이름을 정의하면 속성이있는 위치를 알 수 있습니다. __mro__그 이름을 정의합니다.


9
안녕, alex, D .__ mro__와 D.mro () 사이에 차이점이 있습니까?
zjm1126 2010 년

26
mro메타 클래스에 의해 사용자 정의 될 수 있으며, 클래스 초기화시 한 번 호출되며 결과는 docs.python.org/library/…__mro__ 참조하십시오 .
Alex Martelli

23
속성 확인 순서 대신 메서드 확인 순서 라고 하는 이유는 무엇 입니까?
Bentley4 2013 년

1
@Alex Martelli가 말하고 python-history.blogspot.com/2010/06/… 의 내용과 같이 , mro 속성은 Python 2.2 MRO 및 Python 2.3 MRO (C3)에서만 새 클래스를 사용할 때 추가해야합니다. 사용됩니다.
andy

82

mro()Method Resolution Order를 나타냅니다. 메서드를 검색 한 순서대로 클래스가 파생 된 유형 목록을 반환합니다.

mro () 또는 __mro__ 는 새 스타일 클래스에서만 작동합니다. 파이썬 3에서는 문제없이 작동합니다. 그러나 파이썬 2에서는 이러한 클래스가 object.


10

이것은 아마도 해결 순서를 보여줄 것입니다.

class A(object):
    def dothis(self):
        print('I am from A class')

class B(A):
    pass

class C(object):
    def dothis(self):
        print('I am from C class')

class D(B, C):
    pass

d_instance= D()
d_instance.dothis()
print(D.mro())

그리고 응답은

I am from A class
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]

규칙은 깊이 우선이며,이 경우 D, B, A, C를 의미합니다.

Python은 일반적으로 상속 클래스를 검색 할 때 깊이 우선 순서를 사용 하지만 두 클래스가 동일한 클래스에서 상속 될 때 Python은 mro에서 해당 클래스의 첫 번째 언급을 제거합니다.


1
보시
Stryker입니다.

1
"Python이 mro에서 해당 클래스의 첫 번째 언급을 제거합니다."라는 의미는 무엇입니까?
Ruthvik Vaila

2
@RuthvikVaila : 그 부분이 잘못 언급되었다고 생각합니다. Python의 역사에 관한 이 블로그 게시물 에서 Guido van Rossum은 (Python 2.2에 도입 된 MRO 체계에 대해) "이 검색에서 중복 된 클래스가 있으면 MRO 목록에서 마지막 발생을 제외한 모든 항목이 삭제됩니다"라고 말합니다 (강조 ). 이것은 클래스의 첫 번째 "언급"보다 더 많은 것을 제거 할 수 있음을 의미합니다.
마티

1

해결 순서는 다이아몬드 상속에서 다릅니다.

class A(object):
    def dothis(self):
        print('I am from A class')


class B1(A):
    def dothis(self):
        print('I am from B1 class')
    # pass


class B2(object):
    def dothis(self):
        print('I am from B2 class')
    # pass


class B3(A):
    def dothis(self):
        print('I am from B3 class')


# Diamond inheritance
class D1(B1, B3):
    pass


class D2(B1, B2):
    pass


d1_instance = D1()
d1_instance.dothis()
# I am from B1 class
print(D1.__mro__)
# (<class '__main__.D1'>, <class '__main__.B1'>, <class '__main__.B3'>, <class '__main__.A'>, <class 'object'>)


d2_instance = D2()
d2_instance.dothis()
# I am from B1 class
print(D2.__mro__)
# (<class '__main__.D2'>, <class '__main__.B1'>, <class '__main__.A'>, <class '__main__.B2'>, <class 'object'>)

하지만 해상도가 다른 이유는 무엇입니까?
Vadim

다중 상속 시나리오에서는 지정된 속성이 현재 클래스에서 먼저 검색됩니다. 찾을 수없는 경우 동일한 클래스를 두 번 검색하지 않고 깊이 우선, 왼쪽-오른쪽 방식으로 상위 클래스로 검색을 계속합니다.
Girish Gupta

미안하지만 왜 첫 번째 경우에는 이동 class B3하지만 두 번째 경우에는 class A이후 로 이동합니다class B1
Vadim
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.