Рейтинг користувача: 5 / 5

Активна зіркаАктивна зіркаАктивна зіркаАктивна зіркаАктивна зірка
 

Множинне успадкування — спадкування в класі-нащадку атрибутів відразу декількох батьківських класів.

Лінеаризація в Python — це черговість, при якій проводиться пошук зазначеного атрибута спочатку в класах-нащадків, а потім і в батьківських класах.

Розглянемо прості приклади множинного спадкоємства і лінеаризації в Python-3.

Множинне успадкування і лінеаризація при даному процесі в Python 3 показана на прикладах нижче. При вказівці методів з однаковою назвою у різних класів і різним вмістом успадковується в класі-нащадку той, клас якого прописаний першим при множинному спадкуванні (в круглих дужках після назви класу-нащадка). Це просто перевірити на прикладі нижче, змінюючи послідовність розташування батьківських класів для наслідування у дочірнього класу Child.

Множинне успадкування в Python 3

class Parent():
    def parent_method(self):
        print("First parent class")

class Parent2():
    def parent_method(self):
        print("Second parent class")

class Parent3():
    def parent_method(self):
        print("Third parent class")

class Child(Parent2, Parent, Parent3):
    def child_method(self):
        print("The child method")

child=Child()
child.parent_method()

Якщо ж кожен метод батьківських класів назвати різними назвами, то на прикладі класу-нащадка можна чітко побачити, що в класі нащадку успадковуються всі батьківські методи відразу трьох класів. Виходить множинне спадкування.

class Parent():
    def parent_method(self):
        print("First parent class")

class Parent2():
    def parent_method2(self):
        print("Second parent class")

class Parent3():
    def parent_method3(self):
        print("Third parent class")

class Child(Parent2, Parent, Parent3):
    def child_method(self):
        print("The child method")

child=Child()
child.parent_method()
child.parent_method2()
child.parent_method3()

Лінеаризація в Python-3

Лінеаризація в Python-3 дещо відрізняється від даного процесу в Python-2. У третій версії MRO (Method Resolution Order) в спадкуванні класу-нащадка дотримується порядок проходження батьківських класів, що було і в їх черговості при його оголошенні. Спочатку пошук ведеться в першому оголошеному класі-батьку, потім в другому і так далі. Наочно це побачити можна в прикладі нижче. Другий батьківський клас успадковує метод першого, а клас-нащадок успадковує другий і третій батьківський клас. При виклику класу нащадка метод він візьме третього класу. А при виклику другого класу, виведеться метод першого.

Така лінеаризація будується для класів нового типу.

print(Child.mro()) виведе інформацію як відбувалася лінеаризація, її черговість. Спочатку метод, до якого звертаються, шукається в класі-нащадку, а потім в батьківських класах в порядку черги.

class Parent():
    def parent_method(self):
        print("First parent class")

class Parent2(Parent):
    pass

class Parent3(Parent):
    def parent_method(self):
        print("Third parent class")

class Child(Parent2, Parent3):
    def child_method(self):
        print("The child method")

parent2=Parent2()
parent2.parent_method()
child=Child()
child.parent_method()
print(Child.mro())

Лінеаризація в Python-2

Для класів старого типу в Python-2 пошук атрибутів для наслідування ведеться в глибину (що відрізняється від лінеаризації класів нового типу), що може привести в підсумку до некоректних результатів. Це слід враховувати при програмуванні в різних версіях Пітона.

Використовувати множинне спадкування слід з особливою уважністю, щоб уникнути плутанини і помилок в коді.