Порядок разрешения методов в наследовании Python

| | | | | | | | | | | | | | |

# Показать программу Python
# как работает MRO


class A:

def rk ( self ):

print ( "В классе A" )

class B (A):

def rk ( self ):

print ( "В классе B" )


r = <код класс = " обычный"> B()

r.rk()

Выход:

В классе B 

В приведенном выше примере методы вызываются из класса B, но не из класса A, и это связано с порядком разрешения методов (MRO).
В приведенном выше коде следует следующий порядок — класс B – > класс A
При множественном наследовании методы выполняются в порядке, указанном при наследовании классов. Для языков, поддерживающих одиночное наследование, порядок разрешения методов не интересен, но языки, поддерживающие порядок разрешения множественных методов наследования, очень важны. Давайте рассмотрим еще один пример, чтобы лучше понять порядок разрешения методов:


# Показать программу Python
# как работает MRO


class A:

def rk ( self ):

print ( " В классе A" )

class B (A):

def rk ( self ):

print ( "В классе B" )

class C (A):

def rk ( self ):

print ( " В классе C " )


# упорядочивание классов

class D (B, C):

пройти


r = D ()

r.rk ()

Вывод :

В классе B 

В приведенном выше примере мы используем несколько наследуемых tance, а также называется Алмазное наследство или Смертоносный Алмаз Смерти и выглядит так:

Python следует порядку поиска в глубину и, следовательно, вызывает метод из класса A. Следуя порядку разрешения методов, порядок поиска выглядит вот так.
Класс D – > Класс В - > Класс С - > Класс A
Python следует глубине первого порядка для разрешения методов и атрибутов. Таким образом, в приведенном выше примере он выполняет метод в классе B.

Старый и новый стиль упорядочения:
В более старой версии Python (2.1) мы требуется использовать классы старого стиля, но в Python (3.x и 2.2) нам требуется использовать только новые классы. Классы нового стиля — это те, первый родительский класс которых наследуется от корневого класса объектов Python.


# Класс в старом стиле

class OldStyleClass:

pass


# Новый класс стиля

class NewStyleClass ( object ):

pass

Порядок разрешения методов (MRO) отличается в обоих стилях объявления. Классы старого стиля используют алгоритм DLR или слева направо слева направо , а классы нового стиля используют алгоритм линеаризации C3 для разрешения метода при множественном наследовании. p>

Алгоритм DLR
При реализации множественного наследования Python создает список классов для поиска, поскольку ему необходимо определить, какой метод следует вызывать при вызове экземпляра. Как следует из названия, порядок разрешения метода будет сначала искать глубину, а затем идти слева направо. Например


class A:

передать


class B:

pass


class C (A, B):

пройти



class D (B, A):

pas



class E (C, D):

pass

В приведенном выше примере алгоритм сначала просматривает класс экземпляра для вызываемого метода. Если его нет, то смотрит на первого родителя, если его тоже нет, то считается родитель-родитель. Это продолжается до конца глубины класса и, наконец, до конца унаследованных классов. Таким образом, порядок разрешения в нашем последнем примере будет D, B, A, C, A. Но A нельзя представить дважды, поэтому порядок будет D, B, A, C. Но этот алгоритм меняется по-разному и демонстрируют разное поведение в разное время. Итак, Самуэле Педрони первым обнаружил несоответствие и представил алгоритм линеаризации C3.

Алгоритм линеаризации C3:
Алгоритм линеаризации C3 — это алгоритм, использующий классы нового стиля. Он используется для устранения несогласованности, созданной алгоритмом DLR. Он имеет определенные ограничения:

  • Дети предшествуют своим родителям.
  • Если класс наследуется от нескольких классов, они сохраняются в порядке, указанном в кортеже базового класса.

Алгоритм линеаризации C3 работает в соответствии с тремя правилами:

  • График наследования определяет структуру разрешения методов.
  • Пользователь должен посещать суперкласс только после посещения метода локального класса.
  • Монотонность

Методы для порядка разрешения методов (MRO) класса:
Чтобы получить порядок разрешения класса мы можем использовать атрибут mro() или mro() . Используя эти методы, мы можем отобразить порядок, в котором методы разрешены. Например


# Программа на Python для отображения порядка
# в которой методы разрешено


class A:

def rk ( self ):

print ( "В классе A" )

class B:

def rk ( self ):

print ( "В классе B" )


# упорядочивание классов

class C (A, B):

def __ init __ ( self ):

print ( " Constructor C " )

r = C ( )


# печатает порядок поиска

print (C .__ mro __)

print (C.mro())

Выход:

 Конструктор C ("класс & # 39; __ основной __. С & # 39; >, < класс & # 39; __ основной __. А & # 39; >, < класс & # 39; __ основной __. Б' >, < класс & # 39; объект & # 39; >) [< класс & # 39; __ основной __. С & # 39; >, < класс & # 39; __ основной __. А & # 39; >, < класс & # 39; __ основной __. Б' >, < класс & # 39; объект & # 39; >]