title: If you store optional functionality of a base class in a secondary class, should the secondary class subclass the base class?
body: <p>I know the title is probably a bit confusing, so let me give you an example. Suppose you have a base class <code>Base</code> 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 <code>OptionalStuffA</code> that is always intended to be subclassed together with the base class. Should you also make that secondary class a subclass of <code>Base</code>?</p>
  <p>This is of course only relevant if you have more than one <code>OptionalStuff</code> class and you want to combine them in different ways, because otherwise you don't need to subclass both <code>Base</code> and <code>OptionalStuffA</code> (and just have <code>OptionalStuffA</code> be a subclass of <code>Base</code> so you only need to subclass <code>OptionalStuffA</code>). I understand that it shouldn't make a difference for the MRO if <code>Base</code> is inherited from more than once, but I'm not sure if there are any drawbacks to making all the secondary classes inherit from <code>Base</code>.</p>
  <p>Below is an example scenario. I've also thrown in the <code>QObject</code> 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.</p>
  <pre><code>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
  </code></pre>