← Назад к вопросам

Как работает множественное наследование?

2.3 Middle🔥 201 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Множественное наследование в Python

Множественное наследование — это механизм, при котором класс может наследоваться от нескольких родительских классов одновременно. Python поддерживает эту возможность нативно, в отличие от некоторых других языков (например, Java). Однако это требует понимания алгоритма разрешения порядка методов (MRO — Method Resolution Order).

Базовый синтаксис

class Parent1:
    def method(self):
        return "Parent1"

class Parent2:
    def method(self):
        return "Parent2"

class Child(Parent1, Parent2):
    pass

obj = Child()
print(obj.method())  # Output: Parent1

Порядок наследования в скобках имеет значение. При вызове method() Python ищет реализацию сначала в Parent1, затем в Parent2.

Method Resolution Order (MRO)

Python использует алгоритм C3 Linearization для определения порядка поиска методов. Это обеспечивает:

  • Порядок слева направо, который указан в определении класса
  • Глубину перед шириной при обходе иерархии
  • Монотонность (если A идет до B в MRO родителя, то A должен идти до B и в MRO ребенка)
class A:
    pass

class B(A):
    pass

class C(A):
    pass

class D(B, C):
    pass

print(D.mro())
# Output: [<class D>, <class B>, <class C>, <class A>, <class object>]

Проверить MRO можно через ClassName.mro() или ClassName.__mro__.

Проблема Diamond Problem

Классическая проблема возникает при такой иерархии:

class A:
    def method(self):
        print("A")

class B(A):
    def method(self):
        print("B")
        super().method()

class C(A):
    def method(self):
        print("C")
        super().method()

class D(B, C):
    pass

d = D()
d.method()
# Output:
# B
# C
# A

Спасибо алгоритму C3, каждый класс вызывается ровно один раз, и в правильном порядке. super() здесь работает с MRO, а не просто с прямым родителем.

Super() и кооперативное наследование

class Shape:
    def __init__(self, color):
        self.color = color

class Polygon(Shape):
    def __init__(self, color, sides):
        super().__init__(color)
        self.sides = sides

class Triangle(Polygon):
    def __init__(self, color, sides=3):
        super().__init__(color, sides)

triangle = Triangle("red")
print(triangle.color, triangle.sides)  # Output: red 3

Использование super() обеспечивает гибкость при изменении иерархии классов.

Практические советы

  1. Избегайте сложных иерархий — если множественное наследование запутанное, лучше использовать композицию
  2. Документируйте MRO — особенно если класс наследуется от нескольких родителей
  3. Используйте super() корректно — это гарантирует работу с MRO
  4. Mixins — частый паттерн множественного наследования для добавления функциональности:
class LogMixin:
    def log(self, msg):
        print(f"[LOG] {msg}")

class DatabaseMixin:
    def query(self, sql):
        print(f"Executing: {sql}")

class Service(LogMixin, DatabaseMixin):
    pass

service = Service()
service.log("Started")
service.query("SELECT * FROM users")

Множественное наследование в Python — мощный инструмент, но требует понимания MRO и аккуратного использования.