Arnaud Delobelle <[EMAIL PROTECTED]> wrote: > On Sep 3, 7:00 pm, <[EMAIL PROTECTED]> wrote: >> >> I want to do something like this. My class/instance has a dict as a >> property. I want the instance to catch the change in the dict (change >> in some values, addition/deletion of key/value etc) to be recognized by >> the class instance. >> >> How can I do this? Any suggestions are very well appreciated. >> >> Here is an example of what I want my class to behave: >> >> class test(object): >> def __init__(self): >> self._d = {} >> self._changed = False >> def getd(self): >> print 'called getd' >> return self._d >> # dont know what to do next >> def setd(self,val): >> print 'called setd', key, val >> self._d[key] = val
> Where does the 'key' come from? Perhaps you need to look further into > how properties work. This obviously doesn't work... >> self._changed = True >> d = property(getd,setd,None,None) >> >> def getc(self): >> return self._changed >> changed = property(getc,None,None,None) >> >> if __name__ == '__main__': >> obj = test() >> print 'obj.changed = ', obj.changed >> print >> >> # I want obj to know that its propety d being changed here >> print "t.d['a'] = 1" >> obj.d['a'] = 1 >> print >> >> # I want the "changed" property to be True >> print 'obj.changed = ', obj.changed >> > You can't do that with plain dicts, and I'm not sure it is often a > good idea. However you could create a class that behaves like a dict > but calls a function each time an item is set, e.g. (made up > terminology): >>>> class TriggerDict(object): > ... def __init__(self, trigger, val=None): > ... self.trigger = trigger > ... self.dict_ = val or {} > ... def __setitem__(self, key, val): > ... self.trigger(self, key, val) > ... self.dict_[key] = val > ... def __getitem__(self, key): > ... return self.dict_[key] > ... >>>> def trigger(d, k, v): > ... print '%s => %s' % (k, v) > ... >>>> td = TriggerDict(trigger) >>>> td['spanish'] = 'inquisition' # see side effect below. > spanish => inquisition >>>> td['spanish'] > 'inquisition' >>>> > Obviously your trigger function would set the _changed attribute of > the test object instead. And again it is probably not a good idea > unless you know exactly what you are doing. If it was me, I'd try to > rethink my design instead. Thank you for suggestion, Arnaud. Since you are discouraging this idea of trigger, may I ask an advice of if my intention was legitimate one or not? 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? Thank you again, > -- > Arnaud -- yosuke kimura Center for Energy and Environmental Resources The Univ. of Texas at Austin, USA -- http://mail.python.org/mailman/listinfo/python-list