I'm trying to create a dictionary subclass which allows a dictionary A to be created which will update a value in a pre-exiting dictionary B to equal a string representation of dictionary A. I see it as an observer pattern, without the ability to have multiple objects observing.
i.e.:
import json
from collections import Mapping
class ObservedDict(dict):
def __init__(self, initial_dict, name=None, observer=None, top_level=True):
for k, v in initial_dict.items():
if isinstance(v, dict):
initial_dict[k] = ObservedDict(v, name, observer, top_level=False)
super().__init__(initial_dict)
self.name = name
self.observer = observer
if top_level is True: # initialise the key:value pair in B
observer[name] = json.dumps(initial_dict)
def __setitem__(self, item, value):
if isinstance(value, dict):
_value = ObservedDict(value, self.name, self.observer, top_level=False)
else:
_value = value
super().__setitem__(item, _value)
# Update B
self.observer[self.name] = json.dumps(self)
B = {}
A = ObservedDict({'foo': 1, 'bar': {'foobar': 2}}, 'observed', B)
B is now {'observed': '{"foo": 1, "bar": {"foobar": 2}}'}
and A is {'foo': 1, 'bar': {'foobar': 2}}
. There are three cases for updating a value in the dictionary (ignoring update
and set
for now):
- I can update A's top-level keys, and it works just fine:
A['foo'] = 2
# B is now automatically {'observed': '{"foo": 2, "bar": {"foobar": 2}}'}
- I can update the entirety of a nested dictionary:
A['bar'] = {'foobar': 4}
# B is now automatically {'observed': '{"foo": 2, "bar": {"foobar": 4}}'}
- But, if I edit a nested value by using the
[]
method,self
in__setitem__
is the nested dict, not the whole dictionary with which theObservedDict
class is initialised, so:
A['bar']['foobar'] = 4
# B is now {'observed': '{"foobar": 4}'}
My question is: how do I retain information about the parent dictionary (i.e. the one used to initialise the class) such that on setting a value using the third case, dictionary B
will update and include the whole of dictionary A (matching case 2, in this instance)?