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?
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 metaclassM_B
; suppose we derive C from A and B. The question is: what is the metaclass of C ? Is itM_A
orM_B
?The correct answer (see the book "Putting metaclasses to work" for a thoughtful discussion) is
M_C
, whereM_C
is a metaclass that inherits fromM_A
andM_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:
- You must, because your problem domain requires you to combine two separately-maintained single-inheritance libraries.
- 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?"