Proper way of defining init() methods with different number of parameters (to be used in multiple inheritance)

Viewed 60

This is my current setup:

class Base():
    def __init__(self):
        pass

    # ...other methods

class A(Base):
    def __init__(self, dst, fname, alg, src=None):
       super().__init__()
       # I then use these instance variables throughout instance methods.
       self.src = [] if src is None else src
       self.dst = dst
       self.fname = fname
       self.alg = alg

    # ...other methods

class B(Base):
    def __init__(self, fname):
       super().__init__()
       # I then use these instance variables throughout instance methods.
       self.fname = fname

    # ...other methods

class C(A, B):
    """Here is my problem.
       When I try to inherit A and B this way,
       I keep getting those "missing required positional args..." errors
    """
    def __init__(self, dst, src=None):
       super().__init__()
       # I then use these instance variables throughout instance methods.
       self.fname = fname

    # ...other methods

Here is what I am trying to do right now:

class Base():
    def __init__(self, *args, **kwargs):
        pass

class A(Base):
    def __init__(self, *args, **kwargs):
       super().__init__(*args, **kwargs)

class B(Base):
    def __init__(self, *args, **kwargs):
       super().__init__(*args, **kwargs)

class C(A, B):
    def __init__(self, *args, **kwargs):
       super().__init__(*args, **kwargs)

My main question:

What is the "best" (standard, most preferred, efficient, readable etc.) way to handle such situations?

P.S.

  • I read the following article, Python’s super() considered super!, but I could not derive the best answer for myself after reading it.
  • Also, I referenced this SO question but the accepted answer does not have different number of params like I do...
  • By the way, I am willing to hear that my design (class hierarchy) is bad overall. Technically, I could relocate methods that I am trying to inherit from A and B in C to the Base class...I hope (did not try yet)...
2 Answers

Based on your implementation, to remove the error, I think it would be best to explicitly use the base class' required parameters based on the method resolution order (in your case, the base class for the class C should be class A).

class C(A, B):
    def __init__(self, dst, src=None):
        fname = 'some value'
        super().__init__(dst, fname, alg)

This will be the simplest solution that can be done. But if you are willing to make design changes, I would recommend using composition instead of inheritance for python. I assume that you have methods in class A and class B that is needed by class C. With composition, needed functions/operations can just be added to the classes that needs it. It would also prevent code smells like refused bequest

Python has an advantage that supports multiple inheritance, even the box office technology java doesn't supports this feature because it leads to overriding of methods when both extended class have a same method name.

But python overcomes this problem and supporting multiple inheritance. To use multiple inheritance in python, should know the arguments to define in proper way.

class C(A, B):
    def __init__(self, dst, src=None):
       super().__init__()
       self.fname = fname

In the above obove code, Class C inherits Classes A and B. Here first of all super().__init__() navigate to Class A, search for .__init__(), if init() or some other method abc() not in Class A, then next it will look up into Class B,

These navigation go through based on sequential order that you inherits into Class C

Here Solution for you problem is, you defined super class __init__() with parameters in both Class A & B, and calling super class super().__init__() with out parameters in Class C.

Related