Порядок поиска атрибута при множественном наследовании

42. Порядок поиска атрибута при множественном наследовании

Условие зададчи: Даны два родительских класса с одноименным атрибутом класса x и дочерний класс, который наследуется сразу от обоих родителей.

class A:
    x = 5

class B:
    x = 10

class C(A, B):
    pass
Спойлеры к решению
Подсказки
  • Класс C наследуется сразу от A и B.
  • В Python при множественном наследовании атрибуты ищутся по порядку MRO.
  • MRO — это порядок разрешения методов и атрибутов.
  • Для class C(A, B) сначала проверяется сам C, потом A, потом B.
  • Так как у C собственного атрибута x нет, Python найдёт x в классе A.
Решение
class A:
    x = 5

class B:
    x = 10

class C(A, B):
    pass


print(C.x)
print(C.__mro__)

Результат:

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

При обращении:

C.x

Python ищет атрибут x в таком порядке:

C -> A -> B -> object

В самом классе C атрибута x нет. Затем Python смотрит в первый родительский класс A и находит там:

x = 5

Поэтому результат будет:

5

Атрибут B.x равен 10, но до него поиск не дойдёт, потому что подходящий атрибут уже найден в A.

Если изменить порядок наследования:

class C(B, A):
    pass

тогда результат был бы другим:

print(C.x)  # 10

Потому что порядок поиска стал бы:

C -> B -> A -> object