Python Learner
Python Learner

Reputation: 487

super function in Multiple inheritance in python

I have written this code in python 3.4 and used classes. I have implemented multiple inheritance in this code with super() function. And i want to call the init() function of library class. But i am unable, can anyone tell me the mistake?

code

class college:
    def __init__(self, rollno):
        print("Roll no:", rollno)

class library:
    def __init__(self, libcardno):
        print("Library card no:", libcardno)

class student(college, library):
    def __init__(self, name):
        print("Name:", name)
        super().__init__(5560)
        super().__init__(60)

output

>>> obj = student("John")
Name: John
Roll no: 5560
Roll no: 60

Just understand the question, it's not a duplicate of another one.

Upvotes: 1

Views: 6641

Answers (2)

changhwan
changhwan

Reputation: 1112

Short:

You can't and you don't need to use super() to call __init__ with different form. Of course there is a way to do, but I do not recommend that.

Long:

Python uses the list of classes to inherit from. You can see that list with ClassName.__mro__. mro stands for Method Resolution Order

Think about you have three classes, ClassA, ClassB, ClassC and ClassC extends ClassA, and ClassB (If you are using python2, ClassA and ClassB musts extend from object)

class ClassC(ClassA, ClassB):

Then, ClassC.__mro__ will be like below:

(<class '__main__.ClassC'>, <class '__main__.ClassA'>, <class '__main__.ClassB'>, <class 'object'>)

So python inherits ClassC, ClassA, ClassB order. And it assumes that methods have same form in this list. This is why you can't use different forms of __init__ call using super().

If you need to use super() and there is no option, you can consider passing argument as **kwargs.

class ClassA():
    def __init__(self, **kwargs):
        super(ClassA, self).__init__(**kwargs)
        print("Class A Initialized:", kwargs['a'])

class ClassB():
    def __init__(self, **kwargs):
        # super(ClassA, self).__init__(**kwargs)
        # if you call above, you'll get type error, because above will call object.__init__ which takes only 1 argument
        print("Class B Initialized:", kwargs['b'])

class ClassC(ClassA, ClassB):
    def __init__(self, **kwargs):
        super(ClassC, self).__init__(**kwargs)
        print("Class C Initialized:", kwargs['c'])

ClassC(a="A", b="B", c="C")

And you can get below output :

Class B Initialized: B
Class A Initialized: A
Class C Initialized: C

But still, I recommend that do not use this form of inheritance, because it is very complicated

Upvotes: 2

Mitiku
Mitiku

Reputation: 5412

You can directly call __init__ method of respective parent class.

class student(college, library):
    def __init__(self, name):
        print("Name:", name)
        college.__init__(self,5560)
        library.__init__(self,60)

Upvotes: 4

Related Questions