Best practices for multiple inheritance in this Python code Best practices for multiple inheritance in this Python code tkinter tkinter

Best practices for multiple inheritance in this Python code


I've been reading about multiple inheritance these days and I've learnt quite a lot of things. I have linked my sources, resources and references at the end.

My main and most detailed source has been the book "Fluent python", which I found available for free reading online.

This describes the method resolution order and design sceneries with multiple inheritance and the steps for doing it ok:

  1. Identify and separate code for interfaces. The classes that define methods but not necessarily with implementations (these ones should be overriden). These are usually ABCs (Abstract Base Class). They define a type for the child class creating an "IS-A" relationship

  2. Identify and separate code for mixins. A mixin is a class that should bring a bundle of related new method implementations to use in the child but does not define a proper type. An ABC could be a mixin by this definition, but not the reverse. The mixin doesn't define nor an interface, neither a type

  3. When coming to use the ABCs or classes and the mixins inheriting, you should inherit from only one concrete superclass, and several ABCs or mixins:

Example:

class MyClass(MySuperClass, MyABC, MyMixin1, MyMixin2):

In my case:

class ImgButton(ttk.Button, MyWidget):
  1. If some combination of classes is particularly useful or frequent, you should join them under a class definition with a descriptive name:

Example:

 class Widget(BaseWidget, Pack, Grid, Place):     pass

I think Loggable would be a Mixin, because it gathers convenient implementations for a functionality, but does not define a real type. So:

class MyWidget(ttk.Widget, Loggable): # May be renamed to LoggableMixin
  1. Favor object composition over inheritance: If you can think of any way of using a class by holding it in an attribute instead of extending it or inheriting from it, you should avoid inheritance.

    "Fluent python" - (Chapter 12) in Google books

    Super is super

    Super is harmful

    Other problems with super

    Weird super behaviour


In principle, use of multiple inheritance increases complexity, so unless I am certain of its need, I would avoid it. From your post you already look aware of the use of super() and the MRO.

A common recommendation is to use composition instead of multiple inheritance, when possible.

Another one is to subclass from only one instantiable parent class, using abstract classes as the other parents. That is, they add methods to this subclass, but never get instantiated themselves. Just like the use of interfaces in Java. Those abstract classes are also called mixins, but their use (or abuse) is also debatable. See Mixins considered harmful.

As for your tkinter code, besides logger code indentation, I don't see a problem. Maybe widgets can have a logger instead of inheriting from it. I think with tkinter the danger is the unwanted override by mistake of one of the hundreds of available methods.