Python Mixins

Carl Banks pavlovevidence at gmail.com
Sat Sep 24 05:58:37 EDT 2011


On Thursday, September 22, 2011 2:14:39 PM UTC-7, Matt wrote:
[snip]
> class MyMixin(object):
>     def one_thing(self):
>         return "something cool"
> 
> @mixin(MyMixin)
> class MyClass(object):
>     pass
> 
> x = MyClass()
> x.one_thing() == 'something cool'
> x.__class__.__bases__ ==  (object,)
> 
> To me, this is much more concise. By looking at this I can tell what
> MyClass IS, who it's parents are and what else it can do. I'm very
> interested to know if there are others who feel as dirty as I do when
> using inheritance for mixins

Not me.  Inheritance perfectly encompasses the mixin relationship, and because inheritance is so thoroughly ingrained in Python, it makes sense not to create a completely different mechanism to share behavior just for the case of mixins.

I know that, as someone who reads code, I would rather coders stick to well-known mechanisms than to create their own ad hoc mechanisms that don't actually add any new capability.  Take your MyClass example above.  If you had stuck to inheritance I could have seen what classes all the behavior was implemented by listing the __bases__.  But since you used an ad hoc mechanism, now I have to track down where the hell that one_thing() method is coming from.

No mechanism is ever perfect, and Python's MI is very far from perfect, but sticking to well-known and understood methods is usually more important than whatever little improvement you can make.  (And it is little; best as I can tell, your main objection is that mixins make it harder to see what the "main" parent is.  I'd say that's a dubious justification to spring a new behavior-sharing mechanism on a reader.)


> or if there are other things that Python
> developers are doing to mix in functionality without using inheritance
> or if the general populous of the Python community disagrees with me
> and thinks that this is a perfectly valid use of inheritance.

I'd guess the majority just use inheritance, although I can't say I've seen enough code out there to gauge it.

But there is something else a lot of Pythonistas will do in many cases: just define regular functions.  In your example, instead of defining one_thing() as a method of a mixin, define it as a function.  Personally, I find that I almost never use mixins, though I have absolutely nothing against them and I use MI and metaclasses all the time.  It's just that for most things I'd use a mixin for, I find that one or two regular functions work perfectly well.


Carl Banks



More information about the Python-list mailing list