How can I add an additional class inheritance to an existing one, but with different number of arguments to existing inheritance?

Question:

I have an existing class TSEparser that inherits from a parent class Subparser, but now I want to add another parent class (SubparserMixin) to class TSEparser. However, the problem is that the arguments passed by the initial inheritance gets in the way of this new inheritance- how can I fix this?

i.e:

class Subparser: 
    def __init__(self, filename, data_group, **kwargs):
        self.data_group = data_group
        self.filename = filename
        self.__dict__.update(kwargs)


class TSEparser(Subparser):
    def __init__(self, filename, data_group, **kwargs):
        super().__init__(filename, data_group, **kwargs)

Now I want to add another parent class SubparserMixin so we have class TSEparser(Subparser, SubparserMixin), however Subparsermixin looks like this:

class SubparserMixin:

    def __init__(self):
        self.subparsers = {}
        self.context = PacketContext

Is there some way I can inherit separately from both Parent Classes? Something like this:

class TSEparser(Subparser):
    def __init__(self, filename, data_group, **kwargs):
        super(Subparser).__init__(filename, data_group, **kwargs)
        super(SubparserMixin).__init__() 

I know the syntax is not correct but I hope it is clear what I am trying to do!

Asked By: Patrick_Chong

||

Answers:

You can specify which class’ constructor gets called by simply using its name. So in your example you can just do

class TSEparser(Subparser, SubparserMixin):
    def __init__(self, filename, data_group, **kwargs):
        Subparser.__init__(self, filename, data_group, **kwargs)
        SubparserMixin.__init__(self) 

There is no good and easy way to make this work using super. You can check out this question for more detail. super normally takes care of calling the proper classes for you. If you want to call the __init__ of a specific class manually (e.g. because the required arguments are different), you need to call it directly using its name as shown above.

Edit: My code example mistakenly didn’t pass self when calling the base __init__ methods. Note that this is a difference between calling by super and directly by base class. super doesn’t require self, while direct calling does.

# without self
super().__init__()
# with self
Base.__init__(self)
Answered By: FIlip Müller
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.