728x90
Python에서 다중 상속(Multiple Inheritance)은 한 클래스가 여러 클래스를 상속받을 수 있는 기능을 제공합니다. 다중 상속은 코드의 재사용성을 높이고 다양한 기능을 결합할 수 있는 유용한 방법이지만, 여러 부모 클래스에서 동일한 메서드를 정의할 때 메서드 해석 순서(Method Resolution Order, MRO)에 대한 이해가 중요합니다. MRO는 다중 상속에서 메서드나 속성을 호출할 때, 호출할 부모 클래스가 어떤 순서로 결정되는지를 정의합니다.
다중 상속 (Multiple Inheritance)
다중 상속은 하나의 클래스가 여러 부모 클래스를 상속받는 것을 의미합니다. Python에서는 여러 부모 클래스를 상속받는 것이 가능합니다. 이때 중요한 점은 각 부모 클래스에서 동일한 메서드를 정의하는 경우, 어떤 메서드를 호출할지 결정해야 한다는 것입니다.
class A:
def greet(self):
print("Hello from A!")
class B:
def greet(self):
print("Hello from B!")
class C(A, B):
pass
obj = C()
obj.greet() # 어떤 greet 메서드가 호출될까요?
MRO (Method Resolution Order)
- MRO는 다중 상속에서 메서드를 호출할 때, 어떤 부모 클래스의 메서드가 호출될지 우선순위를 결정하는 규칙입니다.
- Python은 C3 선형화(C3 Linearization) 알고리즘을 사용하여 MRO를 계산합니다.
- Python에서 MRO는 클래스의 상속 트리를 따라 메서드를 찾는 순서이며, MRO가 계산된 순서대로 부모 클래스들의 메서드를 호출합니다.
C3 선형화 알고리즘 (C3 Linearization)
C3 선형화는 MRO를 계산하는 규칙으로, 다중 상속을 처리할 때 부모 클래스의 순서를 결정합니다. 주요 특징은 다음과 같습니다:
자식 클래스에서 메서드를 찾고, 그 클래스가 상속하는 순서대로 부모 클래스를 찾습니다.
부모 클래스는 왼쪽에서부터 우선순위대로 결정됩니다.
상속 관계가 선형적(linear)이도록 계산됩니다
class A:
def greet(self):
print("Hello from A!")
class B:
def greet(self):
print("Hello from B!")
class C(A, B):
pass
print(C.__mro__) # C, A, B, object
# MRO 순서는 C -> A -> B -> object
동작 방식:
- C 클래스에서 greet()를 호출하면, 먼저 C에 해당 메서드가 있는지 확인합니다. C에 greet()가 없으므로 A 클래스에서 greet()를 찾아 호출합니다.
- A에서 greet()가 호출되므로, 출력은 "Hello from A!"입니다.
MRO의 중요성
- 다중 상속을 사용하면서, 메서드 이름이 충돌하는 경우, MRO는 어떤 메서드를 우선 호출할지를 결정해 줍니다. 이를 통해 클래스 계층 구조에서 예상하지 못한 동작을 방지할 수 있습니다.
- super()를 사용하여 메서드 호출 시, MRO에 따라 부모 클래스의 메서드를 호출할 수 있습니다. super()는 MRO를 따라가며 부모 클래스를 호출합니다
class A:
def greet(self):
print("Hello from A!")
super().greet()
class B:
def greet(self):
print("Hello from B!")
super().greet()
class C(A, B):
def greet(self):
print("Hello from C!")
super().greet()
obj = C()
obj.greet()
# C에서 super().greet()가 호출되면, super()는 MRO에 따라 A로 넘어가고, A에서 super().greet()를 호출하면 B로 넘어가게 됩니다.
복잡한 다중 상속 예시
class A:
def greet(self):
print("Hello from A!")
class B(A):
def greet(self):
print("Hello from B!")
class C(A):
def greet(self):
print("Hello from C!")
class D(B, C):
def greet(self):
print("Hello from D!")
obj = D()
obj.greet()
print(D.__mro__) # MRO 출력
# Hello from D!
# [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
'Python' 카테고리의 다른 글
Python의 메모리 관리 방식(Garbage Collection 포함) (0) | 2025.03.10 |
---|---|
__new__와 __init__의 차이 (0) | 2025.03.05 |
Python/Django 기술면접 질문 (0) | 2025.03.05 |
스트라이드와 슬라이스를 한 식에 함께 사용하지 말라 (0) | 2025.02.06 |
:= 바다코끼리 연산자 (0) | 2025.02.06 |