【发布时间】:2019-06-20 22:31:26
【问题描述】:
我正在尝试创建一个字典子类,它允许创建字典 A,它将更新预先存在的字典 B 中的值以等于字典 A 的字符串表示形式。我将其视为观察者模式,没有观察多个对象的能力。
即:
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 现在是{'observed': '{"foo": 1, "bar": {"foobar": 2}}'},A 是{'foo': 1, 'bar': {'foobar': 2}}。更新字典中的值有三种情况(暂时忽略update和set):
- 我可以更新 A 的顶级键,而且效果很好:
A['foo'] = 2
# B is now automatically {'observed': '{"foo": 2, "bar": {"foobar": 2}}'}
- 我可以更新整个嵌套字典:
A['bar'] = {'foobar': 4}
# B is now automatically {'observed': '{"foo": 2, "bar": {"foobar": 4}}'}
- 但是,如果我使用
[]方法编辑嵌套值,__setitem__中的self是嵌套字典,而不是初始化ObservedDict类的整个字典,所以:
A['bar']['foobar'] = 4
# B is now {'observed': '{"foobar": 4}'}
我的问题是:如何保留有关父字典(即用于初始化类的字典)的信息,以便在使用第三种情况设置值时,字典 B 将更新并包含整个字典 A (在这种情况下匹配案例 2)?
【问题讨论】:
-
当创建嵌套的
ObservedDict时,它需要一个额外的参数来告诉它它的父字典。然后,嵌套的 dict 应该只通知其父级有关更改,以便父级(或者可能是进一步向上的祖先)正确处理更改。 -
@jonrsharpe 这是一个
ObservedDict(即我的子类),但是是的,它与A无关,因此我无法从A['bar']访问A。但这是我的问题:如何将A['bar'](和任何其他通用嵌套字典)与A连接起来?
标签: python dictionary subclass observer-pattern