MRO (Method Resolution Order) — это просто правила, по которым Python ищет методы и атрибуты у объектов в иерархии классов.
-
Когда ты вызываешь
obj.method(), Python должен понять в каком классе искатьmethod. -
Если классов несколько (множественное наследование), может быть несколько кандидатов. MRO решает в каком порядке проверять классы, чтобы не запутаться.
По сути: MRO — это список классов, по которому Python идёт сверху вниз, пока не найдёт нужный метод.
Простой пример:
class A:
def say(self):
print("A")
class B(A):
def say(self):
print("B")
class C(A):
def say(self):
print("C")
class D(B, C):
pass
d = D()
d.say()Что напечатает d.say()?
-
Интуитивно: Python должен выбрать между
BиC. -
Тут вступает в силу MRO.
Можно посмотреть:
print(D.__mro__)`Выведет что-то вроде:
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)То есть Python ищет метод в порядке: D → B → C → A → object.
-
Dничего не имеет, идём дальше. -
Bимеетsay→ берём отсюда.
Именно поэтому печатает "B".
💡 Если бы MRO была другой, могло бы печатать "C" или "A".
Python использует алгоритм C3-линеаризации.
-
Он гарантирует: порядок поиска сначала родитель слева, потом справа, но при этом сохраняется порядок, определённый классами.
-
Это важно, чтобы избежать конфликтов при множественном наследовании.
Пример простого множественного наследования:
class X: pass
class Y: pass
class Z(X, Y): passMRO для Z: Z → X → Y → object.
- Сначала проверяем
Z, потом левый родительX, потом правыйY, потомobject.
-
Множественное наследование: без MRO ты бы не знал, какой метод выберется.
-
super(): когда вызываешь
super().method(), Python идёт по MRO.- Это ключевой момент, особенно при цепочках вызовов.
Пример со super():
class A:
def hello(self):
print("A")
class B(A):
def hello(self):
print("B")
super().hello()
class C(A):
def hello(self):
print("C")
super().hello()
class D(B, C):
def hello(self):
print("D")
super().hello()
D().hello()Вывод:
D B C A
super()не всегда идёт просто к родителю, а идёт по MRO → поэтому порядокB → C → Aсовпадает с MRO.
MRO — это "карта" для Python, чтобы найти методы и атрибуты в сложных иерархиях классов и правильно работал super().
Без MRO: множественное наследование было бы хаотичным, супер() не работал бы предсказуемо, методы могли бы неожиданно перезаписываться.
[[IT]] [[Python]]