In our framework we are using a dictionnary that stores the views available for a model. But what happens if you still want to provide a view for a subclass of a model ?
Of course there is still the default view created through introspection but they are only good-looking for very simple models. Thus, in this case, we decided to provide the view from the inherited parent.
Here is the code for an inheritance-aware dictionnary class.
class ClassDict(dict):
"""A dictionnary subclass that uses classes as keys
>>> class A(object): pass
>>> class B(object): pass
>>> class C(B): pass
>>> class D(A, C): pass
>>> class E(D, B): pass
>>> a = A(); b = B(); c = C(); d = D(); e = E()
>>> test = ClassDict()
>>> test[A] = 'A'
>>> test[D]
'A'
>>> try:
... test[b]
... except KeyError:
... print 'Yep'
Yep
>>> test[B] = 'B'
>>> test[E]
'A'
>>> test[C]
'B'
>>> test[c]
'B'
>>> del test[A]
>>> test[d]
'B'
"""
def __getitem__(self, key):
if not isinstance(key, type):
key = key.__class__
found = False
for class_key in key.__mro__:
try:
val = super(ClassDict, self).__getitem__(class_key)
found = True
break
except KeyError:
pass
if found:
return val
raise KeyError
def __setitem__(self, key, value):
if not isinstance(key, type):
key = key.__class__
super(ClassDict, self).__setitem__(key, value)
This kind of dictionnary will only accept new-style classes, moreover if you use an instance as a key, it will use as the key the class of this instance.