trap setting attribute when the attribute is dict

Arnaud Delobelle arnodel at googlemail.com
Mon Sep 3 23:32:57 CEST 2007


On Sep 3, 8:47 pm, <yos... at ccwf.cc.utexas.edu> wrote:

[...]

> My intention was to have a propery 'sum' in my object, and which has sum
> of all the values() of the dict (i have code to make sure that the value
> of dict are all numeric).  I could just the propery being calculated
> everytime the property got __getattr__.  But I thought that it was
> inefficient to calculate the same number over and over when the value is
> already known.  So I was thiking of calculating the number only when the
> dict got modified.
>
> I also experimented with the idea of subclassing dict itself to
> calculate the sum.  Is this what would be better solution?

Why not simply have a method to update the dictionary that also keeps
the sum up to date? Something like that:

>>> class MyObj(object):
...     def __init__(self):
...         self._d = {}
...         self._sum = 0
...     def set_key(self, key, val):
...         self._sum += val - self._d.get(key, 0)
...         self._d[key] = val
...     def get_key(self, key):
...         return self._d[key]
...     def sum(self):
...         return self._sum
...
>>> a = MyObj()
>>> a.set_key(1, 2)
>>> a.sum()
2
>>> a.set_key('a', 10)
>>> a.set_key(1, 5)
>>> a.sum()
15
>>>

Of course this is only worth it if you need to use the sum often
enough.
If you update the dictionary a lot but only need the sum from time to
time, then it might not be worth it at all.

Of course you could subclass dict:

class MyDict(dict):
    def __init__(self, *args, **kwargs):
            self._sum = sum(self.itervalues())
    def __setitem__(self, key, val):
            self._sum += val - self.get(key, 0)
            dict.__setitem__(self, key, val)
    def sum(self):
            return self._sum
    # overload all other methods that mutate the dict
    # to keep _sum up to date

>>> d = MyDict()
>>> d.sum()
0
>>> d['a']=5
>>> d.sum()
5
>>> d['b']=10
>>> d['a']=8
>>> d.sum()
18
>>>

HTH

--
Arnaud





More information about the Python-list mailing list