Login

Inheritance-aware dictionnary

Written on 2008-11-14 11:21.

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.

Note to myself

Written on 2008-07-09 16:42.

How to display numbers and monetary value in a locale aware way

>>> import locale
>>> locale.setlocale(locale.LC_ALL, '')
>>> locale.currency(6512.345)
'6512,35 \xe2\x82\xac'
>>> print locale.currency(6512.345)
6512,35 €
>>> print locale.currency(6512.345, grouping=True)
6.512,35 €
>>> print locale.currency(6512.345, grouping=True, international=True)
6.512,35 EUR
>>> locale.format('%#2.3f', 6512.345, True, False)
'6.512,345'

More info in the python documentation for the locale module

Pages :