Multiple inheritance in python3 with different signatures Multiple inheritance in python3 with different signatures python python

Multiple inheritance in python3 with different signatures


Do not use super(baseclass, ...) unless you know what you are doing. The first argument to super() tells it what class to skip when looking for the next method to use. E.g. super(A, ...) will look at the MRO, find A, then start looking for __init__ on the next baseclass, not A itself. For C, the MRO is (C, A, B, object), so super(A, self).__init__ will find B.__init__.

For these cases, you don't want to use cooperative inheritance but directly reference A.__init__ and B.__init__ instead. super() should only be used if the methods you are calling have the same signature or will swallow unsupported arguments with *args and **vargs. In that case just the one super(C, self).__init__() call would be needed and the next class in the MRO order would take care of chaining on the call.

Putting it differently: when you use super(), you can not know what class will be next in the MRO, so that class better support the arguments you pass to it. If that isn't the case, do not use super().

Calling the base __init__ methods directly:

class A(object):    def __init__(self, a, b):        print('Init {} with arguments {}'.format(self.__class__.__name__, (a, b)))class B(object):    def __init__(self, q):        print('Init {} with arguments {}'.format(self.__class__.__name__, (q)))class C(A, B):    def __init__(self):        # Unbound functions, so pass in self explicitly        A.__init__(self, 1, 2)        B.__init__(self, 3)

Using cooperative super():

class A(object):    def __init__(self, a=None, b=None, *args, **kwargs):        super().__init__(*args, **kwargs)        print('Init {} with arguments {}'.format(self.__class__.__name__, (a, b)))class B(object):    def __init__(self, q=None, *args, **kwargs):        super().__init__(*args, **kwargs)        print('Init {} with arguments {}'.format(self.__class__.__name__, (q)))class C(A, B):    def __init__(self):        super().__init__(a=1, b=2, q=3)