如果dict值都是可序列化的
看起来只需将DictProxy 传递给dict 构造函数,您就可以将数据序列化为JSON。下面的例子来自 Python 3.6:
>>> import multiprocessing, json
>>> m = multiprocessing.Manager()
>>> d = m.dict()
>>> d["foo"] = "bar"
>>> d
<DictProxy object, typeid 'dict' at 0x2a4d630>
>>> dict(d)
{'foo': 'bar'}
>>> json.dumps(d)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
...
TypeError: Object of type 'DictProxy' is not JSON serializable
>>> json.dumps(dict(d))
'{"foo": "bar"}'
如您所见,虽然d 是DictProxy,但使用json.dumps(dict(d)) 而不是json.dumps(d) 允许对数据进行序列化。如果您使用的是json.dump,同样适用。
如果某些dict值也是DictProxies
很遗憾,如果DictProxy 中的值也是DictProxy,则上述方法不起作用。在这个例子中创建了这样一个值:
>>> import multiprocessing
>>> m = multiprocessing.Manager()
>>> d = m.dict()
>>> d["foo"] = m.dict()
解决方案是扩展json.JSONEncoder 类来处理DictProxy 对象,如下所示:
>>> import multiprocessing, json
>>> class JSONEncoderWithDictProxy(json.JSONEncoder):
... def default(self, o):
... if isinstance(o, multiprocessing.managers.DictProxy):
... return dict(o)
... return json.JSONEncoder.default(self, o)
...
>>> m = multiprocessing.Manager()
>>> d = m.dict()
>>> d["foo"] = m.dict()
>>> d["foo"]["bar"] = "baz"
>>> json.dumps(d, cls=JSONEncoderWithDictProxy)
'{"foo": {"bar": "baz"}}'
>>> # This also works:
>>> JSONEncoderWithDictProxy().encode(d)
'{"foo": {"bar": "baz"}}'
当 JSON 编码器遇到 DictProxy 时,会将其转换为 dict,然后对其进行编码。如需更多信息,请参阅Python documentation。