← Назад к вопросам
Какой порядок разрешения доступа к атрибутам при множественном наследовании в Python?
1.8 Middle🔥 171 комментариев
#Python Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Порядок разрешения доступа (MRO — Method Resolution Order)
В Python при множественном наследовании используется алгоритм C3 линеаризация для определения порядка поиска методов и атрибутов. Это обеспечивает монотонность и предсказуемость наследования.
Алгоритм C3 линеаризации
Порядок обхода:
- Сам класс (самый левый)
- Левый родитель и его предки
- Правый родитель и его предки
- object (корневой класс)
class A:
def method(self):
return "A"
class B(A):
pass
class C(A):
def method(self):
return "C"
class D(B, C):
pass
# MRO: D -> B -> C -> A -> object
print(D.mro())
# [<class D>, <class B>, <class C>, <class A>, <class object>]
obj = D()
print(obj.method()) # "C" — найден в C, так как B не переопределяет
Как смотреть MRO
# Способ 1: метод mro()
print(MyClass.mro())
# Способ 2: атрибут __mro__
print(MyClass.__mro__)
# Способ 3: встроенная функция
print(inspect.getmro(MyClass))
Практический пример
class Animal:
def sound(self):
return "Some sound"
class Swimmer:
def sound(self):
return "Splash"
class Walker:
def sound(self):
return "Footsteps"
class Duck(Swimmer, Walker, Animal):
pass
print(Duck.mro())
# [Duck, Swimmer, Walker, Animal, object]
duck = Duck()
print(duck.sound()) # "Splash" — найден в Swimmer (первый в MRO)
Правила C3 линеаризации
Порядок наследования в скобках имеет значение:
class X(A, B): # A имеет приоритет
pass
class Y(B, A): # B имеет приоритет
pass
Монотонность: если класс A предшествует B в MRO родителя, то A должен предшествовать B и в MRO класса.
Проблемы с наследованием
Вот это вызовет ошибку:
class A(B, C):
pass
class D(C, B): # Нарушает порядок!
pass
# TypeError: Cannot create a consistent method resolution order
Правильно:
class A(B, C):
pass
class D(A): # Наследуемся от A, не переопределяем B и C
pass
super() и MRO
Метод super() использует именно MRO для поиска следующего класса:
class Base:
def __init__(self):
print("Base init")
class Mixin:
def __init__(self):
print("Mixin init")
super().__init__()
class Child(Mixin, Base):
def __init__(self):
print("Child init")
super().__init__()
child = Child()
# Child init
# Mixin init
# Base init
Порядок вывода следует C3 MRO: Child -> Mixin -> Base -> object.
Итоги
- MRO определяется алгоритмом C3 линеаризации
- Поиск идёт слева направо по порядку наследования
super()работает с MRO для вызова методов родительских классов- Всегда проверяй MRO при множественном наследовании через
.mro()или.__mro__