I know the title is probably a bit confusing, so let me give you an example. Suppose you have a base class Base
which is intended to be subclassed to create more complex objects. But you also have optional functionality that you don't need for every subclass, so you put it in a secondary class OptionalStuffA
that is always intended to be subclassed together with the base class. Should you also make that secondary class a subclass of Base
?
This is of course only relevant if you have more than one OptionalStuff
class and you want to combine them in different ways, because otherwise you don't need to subclass both Base
and OptionalStuffA
(and just have OptionalStuffA
be a subclass of Base
so you only need to subclass OptionalStuffA
). I understand that it shouldn't make a difference for the MRO if Base
is inherited from more than once, but I'm not sure if there are any drawbacks to making all the secondary classes inherit from Base
.
Below is an example scenario. I've also thrown in the QObject
class as a 'third party' token class whose functionality is necessary for one of the secondary classes to work. Where do I subclass it? The example below shows how I've done it so far, but I doubt this is the way to go.
from PyQt5.QtCore import QObject
class Base:
def __init__(self):
self._basic_stuff = None
def reset(self):
self._basic_stuff = None
class OptionalStuffA:
def __init__(self):
super().__init__()
self._optional_stuff_a = None
def reset(self):
if hasattr(super(), 'reset'):
super().reset()
self._optional_stuff_a = None
def do_stuff_that_only_works_if_my_children_also_inherited_from_Base(self):
self._basic_stuff = not None
class OptionalStuffB:
def __init__(self):
super().__init__()
self._optional_stuff_b = None
def reset(self):
if hasattr(super(), 'reset'):
super().reset()
self._optional_stuff_b = None
def do_stuff_that_only_works_if_my_children_also_inherited_from_QObject(self):
print(self.objectName())
class ClassThatIsActuallyUsed(Base, OptionalStuffA, OptionalStuffB, QObject):
def __init__(self):
super().__init__()
self._unique_stuff = None
def reset(self):
if hasattr(super(), 'reset'):
super().reset()
self._unique_stuff = None