views:

69

answers:

1

I was wondering if I have a couple of models which both include fields like "meta_keywords" or "slug" which have to do with the web page the model instance will be displayed on, whether it would be advisable to break those page metadata elements out into their own class, say PageMeta, and have my other models subclass those via multiple inheritance?

A: 

General advice for a lightly-specified question:

Nontrivial multiple inheritance in Python requires Advanced Techniques to deal with the metaclass/metatype conflict. Look over this recipe from the ActiveState archives and see if it looks like the kind of stuff you like:

Extract from linked recipe:

The simplest case where a metatype conflict happens is the following. Consider a class A with metaclass M_A and a class B with an independent metaclass M_B; suppose we derive C from A and B. The question is: what is the metaclass of C ? Is it M_A or M_B ?

The correct answer (see the book "Putting metaclasses to work" for a thoughtful discussion) is M_C, where M_C is a metaclass that inherits from M_A and M_B.

However, Python is not that magic, and it does not automatically create M_C. Instead, it raises a TypeError, warning the programmer of the possible confusion.

Consequently, I recommend limiting your use of multiple inheritance in Python to the following cases:

  1. You must, because your problem domain requires you to combine two separately-maintained single-inheritance libraries.
  2. You have achieved such fluency with metatype and metaclass that you can write recipe 204197 or its equivalent as easily and confidently as you can write a print statement.

Edit:

Here's Guido van Rossum in An Introduction to Python:

It is clear that indiscriminate use of multiple inheritance is a maintenance nightmare, given the reliance in Python on conventions to avoid accidental name conflicts.

Here he is again in PEP 253, which describes the ideas which were incorporated into Python, but not the implementation:

Metatypes determine various policies for types, such as what happens when a type is called, how dynamic types are (whether a type's dict can be modified after it is created), what the method resolution order is, how instance attributes are looked up, and so on.

I'll argue that left-to-right depth-first is not the best solution when you want to get the most use from multiple inheritance.

I'll argue that with multiple inheritance, the metatype of the subtype must be a descendant of the metatypes of all base types.

This does not mean you shouldn't use multiple inheritance; I'm just warning you so you won't be suprised one day to find yourself slapping your forehead and exclaiming "D'oh! The metatype of one of my subtypes isn't a descendant of the metatypes of all its base types! Don't you hate when that happens?"

Thomas L Holaday
is it that hard to use mixins in python?
rick
@rick, the syntax for multiple inheritance in python is about as easy as it gets; whether it's hard or not ... well, I added four paragraphs from Guido van Rossum so you can get a sense of how the person on Earth who is most familiar with Python feels about multiple inheritance.
Thomas L Holaday
@rick, I hope there's a badge for asking a question which gets only downvoted answers.
Thomas L Holaday
Well, I've used mixins in Django and the boogie-man hasn't come for me ye........
andybak