迈克·布伦南(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对象中每个对象都少实例化一个字典,如果你正在解析一个庞大的文档,这可能是值得的。
str
。 - GoingMyWay