Найти в Дзене
Любитель войти в IT

MRO в Python или как наследуются методы и поля

О чем статья? Приветствую своих читателей! Сегодня поговорим о MRO (Method Resolution Order). Поймем как работает множественное наследование в Python и почему "алмаз" не проблема. Зачем нужно множественное наследование и какие проблемы могут возникнуть? Хмм, никогда не задумывались, что получилось, если бы зебру придумали программисты? Попробуем представить это. Допустим есть 2 класса: Попробуем создать класс "Зебра", который наследуется от предыдущих 2-х. По итогу мы можем использовать методы как и "Лошади", так и "Адидаса". Эврика! Используя множественно наследование, получили нашу простейшую зебру. Напишу коммит и залью на гит ;) На этом моменте у читателей может возникнуть вопрос: что будет, если у классов потомков имеются методы с одинаковым названием? Возникает "проблема алмаза", связанная с ромбовидным наследованием. Для ее решения в Python предусмотрен порядок разрешения методов, так называемый алгоритм С3 - линеаризации. Совсем упрощенно C3 алгоритм MRO можно представить та
Оглавление
В каком порядке будут наследоваться методы и поля?
В каком порядке будут наследоваться методы и поля?

О чем статья?

Приветствую своих читателей!

Сегодня поговорим о MRO (Method Resolution Order). Поймем как работает множественное наследование в Python и почему "алмаз" не проблема.

Зачем нужно множественное наследование и какие проблемы могут возникнуть?

Хмм, никогда не задумывались, что получилось, если бы зебру придумали программисты? Попробуем представить это. Допустим есть 2 класса:

  1. Лошадь, которая говорит "Иго-го!"
  2. Адидас, отличительной чертой которой являются черно-белые полоски на одежде

Попробуем создать класс "Зебра", который наследуется от предыдущих 2-х. По итогу мы можем использовать методы как и "Лошади", так и "Адидаса". Эврика! Используя множественно наследование, получили нашу простейшую зебру. Напишу коммит и залью на гит ;)

Зебра - продукт слияния лошади и адидаса
Зебра - продукт слияния лошади и адидаса

На этом моменте у читателей может возникнуть вопрос: что будет, если у классов потомков имеются методы с одинаковым названием?

Возникает "проблема алмаза", связанная с ромбовидным наследованием.

В Python такой проблемы нет :)
В Python такой проблемы нет :)

Для ее решения в Python предусмотрен порядок разрешения методов, так называемый алгоритм С3 - линеаризации.

Совсем упрощенно C3 алгоритм MRO можно представить так:

  1. В список добавляются родители объекта, начиная слева направо.
  2. В конец списка добавляется список родителей этих родителей и так далее.
  3. Если какой-то класс оказывается в списке дважды, то оставляется только последнее его вхождение.

По своей сути этот алгоритм похож на стандартный обход в ширину, так как двигаемся мы по слоям, не обращаемся к классу-предку до того, как обратимся ко всем его потомкам, даже если потомков у этого предка несколько.

Разберемся на конкретных примерах

TypeError: Cannot create a consistent method resolution order (MRO) for bases object, C, D
TypeError: Cannot create a consistent method resolution order (MRO) for bases object, C, D

Здесь невозможно построить MRO, так как у "E" есть два класса, которые являются прямыми "родственниками", причём "родитель" перечислен до "потомка".

Чтобы закрепить полученные знания, попробуйте определить какой порядок наследования методов и полей будет у класса A.

Ответ на 8 строчке
Ответ на 8 строчке

Подытожим

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

А знали ли вы про MRO? Напишите в комментариях!

Подписывайтесь, здесь будут много крутого контента про IT, python и разработку!