2

我设法将多线程放在 python 脚本中。我使用多处理模块的管理器在多个线程上创建和共享一个字典。

在我的脚本结束时,我想将 dict 作为 json 输出到一个文件中,所以我这样做:

output = open(args.file,'w')
output.write(json.dumps(data))

但是我出错了,说经理字典不可序列化:

TypeError: <DictProxy object, typeid 'dict' at 0x2364210> is not JSON serializable

序列化我的 dict 的聪明方法是什么?我必须将键值复制粘贴到另一个 - 通常 - 吗?

4

2 回答 2

2

如果 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"}'

如您所见, whiled是一个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 编码器遇到 aDictProxy时,它会将其转换为 adict然后对其进行编码。有关详细信息,请参阅Python 文档

于 2017-05-30T16:18:11.783 回答
0

...“相当”简单。

我看到了这个问题的答案

我必须在字典的键上使用 iter() 来创建一个可以序列化的新“常用”字典。

于 2013-03-01T09:13:56.783 回答