A class can be derived from more than one base class in Python, This is called multiple inheritance. In multiple inheritance, the features of all the base classes are inherited into the derived class. The syntax for multiple inheritance is almost similar to single inheritance.
class parent: statements class child1(parent): statements class child2(parent): statements class child3(child1, child2) |
let's quickly tweak the code from inheritance example,
class SchoolMember: def __init__(self, firstname, lastname): self.firstname = firstname self.lastname = lastname def printname(self): print(self.firstname, self.lastname) class Teacher(SchoolMember): def __init__(self, firstname, lastname): super().__init__(firstname, lastname) def teacher_database(self): print(self.firstname, self.lastname, "has access to the teacher database") class Student(SchoolMember): def __init__(self, firstname, lastname): super().__init__(firstname, lastname) def student_database(self): print(self.firstname, self.lastname, "has access to the student database") class Headmaster(Teacher, Student): def __init__(self, firstname, lastname): Teacher.__init__(self, firstname, lastname) Student.__init__(self, firstname, lastname) teacher_obj1 = Teacher("John", "Michael") student_obj1 = Student("Michael", "Jackson") |
In the above example, additionally added class Headmaster which inherits base class Teacher & Student.
teacher_obj1 has access to the teacher database but not to the student database as 'Teacher' object has no attribute 'student_database'.
teacher_obj1 = Teacher("John", "Michael") teacher_obj1.teacher_database() #Output: John Michael has access to the teacher database teacher_obj1.student_database() #Error: AttributeError: 'Teacher' object has no attribute 'student_database' |
student_obj1 has access to the student database but not to the teacher database as 'Student' object has no attribute 'teacher_database'.
student_obj1 = Student("Michael", "Jackson") student_obj1.student_database() #Output: Michael Jackson has access to the student database student_obj1.teacher_database() #Error: 'Student' object has no attribute 'teacher_database' |
In some cases, Headmaster may have access to both the teacher & student database. To do this, Headmaster has to inherit multiple base classes, Teacher & Student.
class Headmaster(Teacher, Student): def __init__(self, firstname, lastname): Teacher.__init__(self, firstname, lastname) Student.__init__(self, firstname, lastname) headmaster_obj1 = Headmaster("Sachin", "Tendulkar") headmaster_obj1.teacher_database() headmaster_obj1.student_database() |
headmaster_obj1 has access to both attribute and member functions in Teacher & Student as it inherits both base classes, Teacher & Student. This is why we call it multiple inheritances.
Method Resolution Order (MRO) is the order in which Python looks for a method in a hierarchy of classes. Especially it plays vital role in the context of inheritance.
class A: num = 100 class B(A): num = 100000 class C(A): num = 1000 class D(B, C): pass print(D.num) #Output: 100000 |
class A: num = 100 class B(A): num = 100000 class C(A): num = 1000 class D(C, B): pass print(D.num) #Output: 1000 |
Did you notice the outputs in above examples ? because python constructs the order in which it will look for a methods\attributes in the hierarchy of classes. This order is known as MRO, to determine which method it actually calls.
Using mro() or __mro__, you can determine which method it actually calls.
print(D.mro()) or print(D.__mro__) #Dunder Method |
[<'class '__main__.D'>, <'class '__main__.B'>, <'class '__main__.C'>, <'class '__main__.A'>, <'class 'object'>] |
[<'class '__main__.D'>, <'class '__main__.C'>, <'class '__main__.B'>, <'class '__main__.A'>, <'class 'object'>] |
If you have any doubts or queries related to this chapter, get them clarified from our Python Team experts on ibmmainframer Community!