How can I make a dictionary that marks itself when it's modified?
Michael Spencer
mahs at telcopartners.com
Thu Jan 12 13:59:39 EST 2006
sandravandale at yahoo.com wrote:
> It's important that I can read the contents of the dict without
> flagging it as modified, but I want it to set the flag the moment I add
> a new element or alter an existing one (the values in the dict are
> mutable), this is what makes it difficult. Because the values are
> mutable I don't think you can tell the difference between a read and a
> write without making some sort of wrapper around them.
>
> Still, I'd love to hear how you guys would do it.
>
> Thanks,
> -Sandra
>
Sandra
You appear to want:
D = {"a":obj1, "b":obj2}
when obj1 or obj2 changes, to notify D
I think that's hard to do in the general case (i.e., for any value of obj). You
will have to design/modify obj1 and obj2 or wrap them it to achieve this. If
the objects are not homogeneous, I'd give up ;-)
If you can design obj for the purpose it shouldn't be do hard, using the
observer pattern:
Here's a sketch:
class Observable(object):
"""An object that notifies observers when it is changed"""
def __init__(self):
self._observers = []
def add_observer(self, observer):
self._observers.append(observer)
def _notify(self, attrname, newval):
for observer in self._observers:
observer.notify(self, attrname, newval)
def __setattr__(self, attrname, val):
object.__setattr__(self, attrname, val)
self._notify(attrname, val)
class DictObserver(dict):
"""A dict that observes Observable instances"""
def __setitem__(self, key, value):
assert isinstance(value, Observable)
dict.__setitem__(self, key, value)
value.add_observer(self)
def notify(self, obj, attr, newval):
print "%s.%s = %s" % (obj, attr, newval)
>>> a = Observable()
>>> b = Observable()
>>> D = DictObserver()
>>> D["a"] = a
>>> D["b"] = b
>>> a.new_attribute = 4
<observer_dict.Observable object at 0x01AE9210>.new_attribute = 4
>>> b.new_attribute = 6
<observer_dict.Observable object at 0x01AE98F0>.new_attribute = 6
>>> a.new_attribute = 5
<observer_dict.Observable object at 0x01AE9210>.new_attribute = 5
>>>
Michael
More information about the Python-list
mailing list