Jun-20-2020, 02:41 PM
(This post was last modified: Jun-21-2020, 05:07 PM by Gribouillis.)
I guess you want to change the minimal amount of code to your existing program. It could be as simple as using a subclass of
You can then update a GUI instead of printing messages.
dict
for the variable that you are observing. For example with the MyDict
class below, all the changes to the dictionary will trigger a printed message. You don't need to change anything to the existing code. Just inject the MyDict object where it is needed.You can then update a GUI instead of printing messages.
__version__ = '2020.06.21' sentinel = object() class Observer: def on_item_added(self, k, v): print('added item', k, v) def on_value_changed(self, k, v, old): print('value changed', k, v, old) def on_item_removed(self, k, v): print('item removed', k, v) def on_cleared(self): print('dict cleared') class MyDict(dict, Observer): def __setitem__(self, k, v): w = super().get(k, sentinel) super().__setitem__(k, v) if w is sentinel: self.on_item_added(k, v) else: self.on_value_changed(k, v, w) def __delitem__(self, k): self.pop(k) def clear(self): super().clear() self.on_cleared() def pop(self, k, d=sentinel): try: v = super().pop(k) except ValueError: if d is sentinel: raise else: return d else: self.on_item_removed(k, v) return v def popitem(self): k, v = super().popitem() self.on_item_removed(k, v) return (k, v) def update(self, *args, **kwargs): if args: if len(args) != 1: raise TypeError( 'update expected at most 1 argument, got', len(args)) E = args[0] if hasattr(E, 'keys'): for k in E: self[k] = E[k] else: for k, v in E: self[k] = v for k in kwargs: self[k] = kwargs[k] def setdefault(self, k, d=None): if k not in self: self[k] = d return self[k] if __name__ == '__main__': d = MyDict() # This code is exactly the same as in an ordinary dictionary. d[3] = "foo" d.update({4:'bar', 5:'spam'}) del d[4] d.clear() d.setdefault(8, 'eggs') d[8] = 9
Output:added item 3 foo
added item 4 bar
added item 5 spam
item removed 4 bar
dict cleared
added item 8 eggs
value changed 8 9 eggs