trap setting attribute when the attribute is dict

yosuke at ccwf.cc.utexas.edu yosuke at ccwf.cc.utexas.edu
Mon Sep 3 22:31:56 EDT 2007


Arnaud Delobelle <arnodel at googlemail.com> wrote:
> 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
>>>>

Thank you.  I will go with subclassing method.

-- 
yosuke kimura
Center for Energy and Environmental Resources
The Univ. of Texas at Austin, USA



More information about the Python-list mailing list