택시짱의 개발 노트

mro(method resolution order)가 뭐지..? 본문

python

mro(method resolution order)가 뭐지..?

택시짱 2022. 3. 22. 22:30

mro 란?

method resolution order로 메서드 결정 순서이다. ( 자식과 부모 클래스를 전부 포함하여 메서드의 실행 순서를 지정하는 것)

 

왜 mro라는게 있을까?

python은 기본적으로 다중 상속을 지원한다.

상속받은 부모 클래스가 서로 겹치지 않은 메서드 네임을 가지고 있다면 자식 클래스에서 부모 클래스의 메서드를 사용할때 딱히 문제가 되지 않는데 BUT 부모 클래스가 가지고 있는 메서드의 이름이 모두 같다면 자식 클래스는 어떤 부모 클래스의 메서드를 불러와야할까??

아래의 같은 경우에는 어떻게 해야 될까..??

어떤 부모의 메서드를 불러와야 되지..????????

 

정답은 자식에서 상속 받기 위해 작성한 부모 클래스의 순서에 있다.  (왼쪽에서 오른쪽으로)

class A:
    def name(self):
        print('A')


class B:
    def name(self):
        print('B')


class C:
    def name(self):
        print('C')


class D(A, B, C):
    pass


d = D()
d.name()
print(C.__mro__)

>>> A
>>> (<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>)

 

현재 C라는 자식 클래스는 왼쪽을 시작으로 A, B, C 부모 클래스를 상속 받고 있다.

그래서 d.name()을 호출하면 A가 출력되고 있고

여기서 현재 클래스의 mro를 확인하는 방법은 클래스.__mro__를 호출하면 된다.

 

그래서 print(C.__mro__)는 위와 같이 D, A, B , C, object가 나오는것을 확인할 수 있다.

 

이때 A의 name 메서드를 삭제하면 어떻게 될까?

class A:
    # def name(self):
    #     print('A')
    pass

class B:
    def name(self):
        print('B')


class C:
    def name(self):
        print('C')


class D(A, B, C):
    pass


d = D()
d.name()

>>> B
>>> (<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>)

A의 name 메서드를 삭제하게 되면 mro의 다음 순서에 있는 클래스에서 name 메서드를 찾게 된다.

그래서 d.name()은 B를 출력하게 된다!!

 

상속을 할때 주의 해야하는 부분도 있다. 아래와 같은 경우에는 error가 발생하기도 한다.

class A:
    def name(self):
        print('A')

class B(A):
    def name(self):
        print('B')


class C(A):
    def name(self):
        print('C')


class D(A, B, C):
    pass


d = D()
d.name()

Error발생
TypeError: Cannot create a consistent method resolution
order (MRO) for bases A, B, C

A는 B와 C의 부모 클래스 이다. mro순서로 보면 B와 C가 A보다 먼저 있는데

D에서 A, B, C 순서로 상속을 받게되면 B, C에서 A를 상속 받았기 때문에 상속 순서에 대한 문제가 발생하게 된다.

반응형
Comments