【问题标题】:Python multithreading : manager dict not serializablePython多线程:管理器字典不可序列化
【发布时间】:2013-03-01 08:55:15
【问题描述】:

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

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

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

但我出错了,说经理 dict 不可序列化:

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

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

【问题讨论】:

    标签: python json serialization dictionary multiprocessing


    【解决方案1】:

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

    如您所见,虽然dDictProxy,但使用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

    【讨论】:

      【解决方案2】:

      ...“相当”简单。

      我看到了this answer 的一个问题。

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

      【讨论】:

        猜你喜欢
        • 2014-03-15
        • 1970-01-01
        • 2010-10-08
        • 2018-06-27
        • 1970-01-01
        • 2013-12-23
        • 2017-05-16
        • 2018-01-01
        • 1970-01-01
        相关资源
        最近更新 更多