Wednesday, May 14, 2014

Python Mix-ins

Python mix-ins are a handy way to augment functionality of a class.  LinuxJournal has a good detailed article about them.  To mix in a class dynamically you just need to modify the __bases__ class attribute:

class Base(object):pass
class BaseClass(Base):pass
class MixInClass(object):pass

BaseClass.__bases__ += (MixInClass,)

Note that you seem to only be able to do thsi if the base class doesn't inherit directly from object, hence the extra "Base" class above. This is what the failure looks like:
In [10]: class BaseClass(object):pass

In [11]: class MixInClass(object):pass

In [12]: BaseClass.__bases__ += (MixInClass,)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
 in ()
----> 1 BaseClass.__bases__ += (MixInClass,)

TypeError: Cannot create a consistent method resolution
order (MRO) for bases MixInClass, object
Also note that unless both classes call super in their __init__ you will have problems with initialization. It is also possible to mix in a class to an object instance, instead of a class, as mentioned on Stack Overflow like this:
obj = BaseClass()
obj.__class__ = type('MixInClass',(BaseClass,MixInClass),{})

No comments: