[Tutor] 'Right' way to implement mixins in Python?

chombee chombee at nerdshack.com
Thu May 29 01:20:32 CEST 2008


Thanks Alan. Well, it looks like I've worked it out as far as small
example programs go, hope I can get it working in my actual codebase
now.

On Wed, 2008-05-28 at 23:30 +0100, Alan Gauld wrote:
> > It seemed to me that the most natural way to implement mixins in 
> > Python
> > is to use multiple inheritance with new-style classes. But I 
> > certainly
> > confused myself a lot trying to do it.
> 
> Mixins are normally done using MI. I''m interested in your 
> experiences.
> Did new style classes specifically add problems(I've only done mixins
> in old style classes in Python, I've mainly used mixins in Lisp)

The reason I started using new-style classes was that I had a diamond
shape in my class inheritance hierarchy. All my mixin classes inherited
from a single base class, and then all my widget classes
multiple-inherited from selections of mixin classes. (I realise this is
wrong now, but that's how I had it.)

So to get the method resolution order working right with this diamond
formation, I needed new-style classes. And with this diamond formation,
to prevent the __init__ method of the base class being called many times
when a widget class inherits many mixin classes, you have to use super()
instead of explicit calls to all the parent __init__ methods. Then you
run into  a problem when the parameters taken the by __init__ methods of
the mixins do not match each other or the paramaters taken by the
__init__ method of the base class. If a multiple-inheriting widget class
has in its class ancestry a number of different __init__ methods with
different parameter lists, how can it call them all with a single use of
super?

So then you have to use *args and **kwargs in the __init__ method of
_every_ class instead of specifying the parameters normally, and this
has a disadvantage, that the checking of the parameter lists that Python
would normally do is circumvented and you end up having to reimplement
it yourself. By this time I was pretty put off by this approach, and was
getting TypeErrors in my implementation, and decided not to push forward
with it.

Basically, I think that super in Python is a total mess, very tricky and
unwieldy. To be avoided. And also, I think multiple inheritance is
tricky and to be used minimally, avoiding diamond formations or worse. I
understand now why Java does not allow multiple inheritance.

But it all stemmed from my initial mistake, of having all the mixin
classes inherit from a common base class. Take away that and you get rid
of the diamond inheritance formation, you no longer need to use super,
in fact, I probably don't need to use new-style classes at all.

That's an entire days work summed up, trying to refactor my codebase to
use mixins.




More information about the Tutor mailing list