Use case for multiple inheritance (was Re: MRO problems with diamond inheritance?)

Michele Simionato michele.simionato at gmail.com
Tue May 3 01:21:43 EDT 2005


AFAIK, the best use case for multiple inheritance is the plugin
pattern,
when you plug in methods in a class according to a given condition.

For instance:

if plugin == "PDF":
    class DocumentGenerator(BaseGenerator, PDFMixin): pass
elif plugin == "PS":
    class DocumentGenerator(BaseGenerator, PSMixin): pass
elif plugin == "HTML":
    class DocumentGenerator(BaseGenerator, HTMLMixin): pass

etc. This is not a bad use case (actually it is good) still I would say
it
is not compelling. I could just add the right methods by hand:

if plugin == "PDF":
    DocumentGenerator = type("DocumentGenerator", (BaseGenerator,),
PDFmethods)
elif plugin == "PS":
    DocumentGenerator = type("DocumentGenerator", (BaseGenerator,),
PSmethods)
elif plugin == "HTML":
    DocumentGenerator = type("DocumentGenerator", (BaseGenerator,),
HTMLmethods)
or use a different design based on composition + delegation.

The problem with MI is that it does not really give anything new that
you cannot do in other ways (at least in a dynamic language such as
Python); OTOH, it is extremely easily abused and makes difficult to
reason about code. Look to what happened to Zope 2!

Adding methods by hand is ugly, people would think twice before doing
that;
OTOH, using mixin is even worse, still it looks cool and people do not
realize how bad it is. Here I speak for personal experience, as you may

imagine, having both read and written MI hierarchies that could have
much better written without MI. Finally, let me say that cooperative
methods are terrible for maintenance. Nowadays, I tend to use MI just
for debugging (yes, a mixing is convenient, if not compelling, for
adding debugging functionality to a class).


              Michele Simionato




More information about the Python-list mailing list