trap setting attribute when the attribute is dict
Arnaud Delobelle
arnodel at googlemail.com
Mon Sep 3 14:47:16 EDT 2007
On Sep 3, 7:00 pm, <yos... at ccwf.cc.utexas.edu> wrote:
> Hello all,
>
> I have a question which might be simple or need some work around.
>
> 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.
> 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.
HTH
--
Arnaud
More information about the Python-list
mailing list