2

私はなんとかマルチスレッドを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

私の口述をシリアル化する賢い方法は何ですか?キー値を別の-通常の-にコピーして貼り付ける必要がありますか?

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 値が DictProxy でもある場合

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 ドキュメントを参照してください。

于 2017-05-30T16:18:11.783 に答える
0

... "ものすごく単純。

私はこの問題の答えを見ました。

シリアル化できる新しい「通常の」キーを作成するには、辞書のキーでiter()を使用する必要があります。

于 2013-03-01T09:13:56.783 に答える