2

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)...
tera_789
  • 489
  • 4
  • 20
  • 1
    If `A` and `B` require such different signatures, with required positional arguments, should you even be inheriting `C` from both `A` and `B`? How do you expect users of the class to make sense of it and in what example does this make sense? – Grismar Mar 10 '20 at 06:51
  • @Grismar good point I guess...like I mentioned, maybe my logic does not make sense. The reason why I wanted to inherit from A and B is because they both have some methods that I'd like to use in C. Should I just move out those common methods to the Base class? – tera_789 Mar 10 '20 at 06:53
  • can you share how you are using classes ? – sahasrara62 Mar 10 '20 at 06:59

2 Answers2

0

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

catzilla
  • 1,901
  • 18
  • 31
0

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.

Saisiva A
  • 595
  • 6
  • 24