Множинне успадкування — спадкування в класі-нащадку атрибутів відразу декількох батьківських класів.
Лінеаризація в 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 пошук атрибутів для наслідування ведеться в глибину (що відрізняється від лінеаризації класів нового типу), що може привести в підсумку до некоректних результатів. Це слід враховувати при програмуванні в різних версіях Пітона.
Використовувати множинне спадкування слід з особливою уважністю, щоб уникнути плутанини і помилок в коді.