Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python multiple inheritance is not showing class variables or method of second inherited base class

Hello awesome community, I was learning the OOPS concepts with python as a part of my curriculum. I am having a problem with multiple inheritance in python. The following is my code:

#!/usr/bin/env python

class Base1(object):
    def __init__(self):
        self.base1var = "this is base1"


class Base2(object):
    def __init__(self):
        self.base2var = "this is base2"

class MainClass(Base1, Base2):
    def __init__(self):
        super(MainClass, self).__init__()


if __name__ == "__main__":
    a = MainClass()
    print a.base1var
    print a.base2var

and when running, I am getting the following error

print a.base2var
AttributeError: 'MainClass' object has no attribute 'base2var'

If I swap the order of classes inherited, the variable name in the error changes accordingly.

Am I using super() wrong when I want to call the constructors of the two inherited classes?

How can I correctly inherit from multiple base classes and use the variables and methods in the main class without this error?

Thank you.

like image 616
file2cable Avatar asked Jan 03 '18 18:01

file2cable


People also ask

Why multiple inheritance is not supported in Python?

Multiple inheritance is useful in many situations as a developer, but it greatly increases the complexity of the language, which makes life harder for both the compiler developers and the programmers. One problem occurs when two parent classes have data members or methods of the same name.

How does Python handle multiple inheritance?

Inheritance is the mechanism to achieve the re-usability of code as one class(child class) can derive the properties of another class(parent class). It also provides transitivity ie. if class C inherits from P then all the sub-classes of C would also inherit from P.

Can a Python class inherit from multiple classes?

A class can be derived from more than one base class in Python, similar to C++. This is called multiple inheritance. In multiple inheritance, the features of all the base classes are inherited into the derived class.

Does Python support multiple inheritance in Python?

Python is one of the few modern programming languages that supports multiple inheritance. Multiple inheritance is the ability to derive a class from multiple base classes at the same time.


2 Answers

You need to add a super call to Base1 so that Base2's __init__ will get called after Base1's. You can also add a super call to Base2. It's not necessary, but it won't hurt.

class Base1(object):
    def __init__(self):
        super(Base1, self).__init__()
        self.base1var = "this is base1"

class Base2(object):
    def __init__(self):
        #super(Base2, self).__init__()
        self.base2var = "this is base2"

class MainClass(Base1, Base2):
    def __init__(self):
        super(MainClass, self).__init__()


if __name__ == "__main__":
    a = MainClass()
    print a.base1var
    print a.base2var

output

this is base1
this is base2

BTW, you really should be using Python 3. super is much nicer in modern Python. :)

like image 147
PM 2Ring Avatar answered Nov 14 '22 21:11

PM 2Ring


If you use super(), you must use it consistently to ensure all classes' methods are called. Your Base1 and Base2 classes should also call super(...).__init__() in their __init__() methods. This will ensure that all classes in the method resolution order are eventually called.

This does get a little tricky when not all __init__() methods have an empty argument list. At some point, super() will have you calling object.__init__(), and that never takes any arguments. The trouble is, you might not know which classes this might happen in ahead of time. You can remedy this by creating an object subclass that takes any number of arguments in __init__(), and deriving from that. That class needn't call object.__init__() because that method doesn't actually do anything (or, if you're paranoid that that might change, you can call object.__init__() without using super()).

In general, super() requires extra care in argument handling because you might not know which class will be next in the method resolution order, since users of your code might make new classes using your base classes in combinations you haven't anticipated. So you'll need to do some work to make sure the method signatures in all your classes are compatible.

For more information, see Raymond Hettinger's seminal Python's Super() Considered Super.

like image 30
kindall Avatar answered Nov 14 '22 22:11

kindall