[Tutor] What is a mixin class?

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Wed Jan 17 21:57:11 CET 2007



On Wed, 17 Jan 2007, Don Taylor wrote:

> I have a vague idea what a mixin class is, I would like to get a better 
> handle on it.

Hi Don,

This post might help:

     http://mail.python.org/pipermail/tutor/2006-October/050448.html


The core idea is that, since classes themselves are first-class objects, 
we can pass classes around to functions.  More importantly, we can make 
classes on-the-fly.

If we have some class C on hand, we can easily build a subclass.  For 
example:

########################
def do_nothing_mixin(C):
     class S(C):
         pass
     return S
########################

Here, do_nothing_mixing takes in a class C and returns a class S, where S 
is a child subclass of C.  Of course, this example is a bit useless. 
*grin*


But here's a slightly more interesting one:

#######################################
def observer_mixin(C):
     class S(C):
         def __init__(self, *args, **kwargs):
             C.__init__(self, *args, **kwargs)
             self.__listeners = []
         def add_listener(self, l):
             self.__listeners.append(l)
         def notify(self, obj):
             for l in self.__listeners:
                 l.notified(obj)
     return S
#######################################


This captures most of the "Observer" design pattern (without 
thread-safety, but it wouldn't be hard to add that feature in).

We can now add observer capabilities to an arbitrary class:

#######################################################################
class Person:
     def __init__(self, name):
         self.name = name
     def notified(self, obj):
         print "Oh, I %s have been notified about %r" % (self.name, obj)

Announcer = observer_mixin(Person)

ann = Announcer("bart")
others = [Person("Lisa"), Person("Marge"), Person("Homer")]
for o in others:
     ann.add_listener(o)

ann.notify("donut")
#######################################################################

Note here that we have a pre-existing Person class, and we create a new 
kind of Person called an Announcer.  This Announcer is a person, but can 
also act as an observer.


> It is a term that is used quite often in Python circles, but I can't
> find a definition.

One definition (not the only possible one) could be:

     mixin: a function that takes in an input class and produces
     an output class that's guaranteed to be a subclass of the input.

There are other ways to get mixin-like functionality, which is why it's 
necessary to come to terms.



> I notice that Ruby has single inheritance plus mixin classes so maybe 
> somebody who knows Ruby could throw some light on in what way a mixin is 
> different from normal superclass.

'modules' in Ruby are injectable into the definitions of other classes. 
The mechanism, then, is slightly different than what's presented here, but 
the end effect is pretty similar.


If you have more questions, please feel free to ask.


More information about the Tutor mailing list