我设法将多线程放在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的聪明方法是什么?我是否必须将键值复制粘贴到另一个-usual-one?
答案 0 :(得分:0)
答案 1 :(得分:0)
看起来简单地通过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
,则同样适用。
不幸的是,如果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。