Mike Brennanの答えは近いですが、構造全体を再走査する理由はありません。object_hook_pairs
(Python 2.7+)パラメータを使用する場合:
object_pairs_hook
ペアの順序付きリストでデコードされたオブジェクトリテラルの結果で呼び出されるオプションの関数です。の戻り値がのobject_pairs_hook
代わりに使用されdict
ます。この機能を使用して、キーと値のペアがデコードされる順序に依存するカスタムデコーダーを実装できます(たとえば、collections.OrderedDict
挿入の順序を記憶します)。object_hook
も定義されている場合は、object_pairs_hook
が優先されます。
これにより、各JSONオブジェクトが渡されるので、再帰を必要とせずにデコードを実行できます。
def deunicodify_hook(pairs):
new_pairs = []
for key, value in pairs:
if isinstance(value, unicode):
value = value.encode('utf-8')
if isinstance(key, unicode):
key = key.encode('utf-8')
new_pairs.append((key, value))
return dict(new_pairs)
In [52]: open('test.json').read()
Out[52]: '{"1": "hello", "abc": [1, 2, 3], "def": {"hi": "mom"}, "boo": [1, "hi", "moo", {"5": "some"}]}'
In [53]: json.load(open('test.json'))
Out[53]:
{u'1': u'hello',
u'abc': [1, 2, 3],
u'boo': [1, u'hi', u'moo', {u'5': u'some'}],
u'def': {u'hi': u'mom'}}
In [54]: json.load(open('test.json'), object_pairs_hook=deunicodify_hook)
Out[54]:
{'1': 'hello',
'abc': [1, 2, 3],
'boo': [1, 'hi', 'moo', {'5': 'some'}],
'def': {'hi': 'mom'}}
を使用するとすべてのオブジェクトがフックに渡されるため、フックを再帰的に呼び出す必要がないことに注意してくださいobject_pairs_hook
。リストを気にする必要はありますが、ご覧のとおり、リスト内のオブジェクトは適切に変換され、それを実行するために再帰する必要はありません。
編集:同僚は、Python2.6にはがないことを指摘しましたobject_hook_pairs
。非常に小さな変更を加えるだけで、Python2.6を使用できます。上記のフックで、次のように変更します。
for key, value in pairs:
に
for key, value in pairs.iteritems():
次にのobject_hook
代わりに使用しますobject_pairs_hook
:
In [66]: json.load(open('test.json'), object_hook=deunicodify_hook)
Out[66]:
{'1': 'hello',
'abc': [1, 2, 3],
'boo': [1, 'hi', 'moo', {'5': 'some'}],
'def': {'hi': 'mom'}}
object_pairs_hook
結果を使用すると、JSONオブジェクトの各オブジェクトに対してインスタンス化される辞書が1つ少なくなります。これは、巨大なドキュメントを解析している場合、価値があるかもしれません。
str