La réponse de Mike Brennan est proche, mais il n'y a aucune raison de traverser à nouveau la structure entière. Si vous utilisez le object_hook_pairs
paramètre (Python 2.7+):
object_pairs_hook
est une fonction facultative qui sera appelée avec le résultat de tout objet littéral décodé avec une liste ordonnée de paires. La valeur de retour de object_pairs_hook
sera utilisée à la place de dict
. Cette fonctionnalité peut être utilisée pour implémenter des décodeurs personnalisés qui reposent sur l'ordre de décodage des paires clé / valeur (par exemple, collections.OrderedDict
se souviendront de l'ordre d'insertion). Si object_hook
est également défini, le object_pairs_hook
prend la priorité.
Avec lui, vous obtenez chaque objet JSON, vous pouvez donc faire le décodage sans avoir besoin de récursivité:
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'}}
Notez que je n'ai jamais à appeler le crochet de manière récursive car chaque objet sera remis au crochet lorsque vous utiliserez le object_pairs_hook
. Vous devez vous soucier des listes, mais comme vous pouvez le voir, un objet dans une liste sera correctement converti, et vous n'avez pas besoin de récursivement pour y arriver.
EDIT: Un collègue a souligné que Python2.6 n'a pas object_hook_pairs
. Vous pouvez toujours utiliser cette volonté Python2.6 en faisant un très petit changement. Dans le crochet ci-dessus, modifiez:
for key, value in pairs:
à
for key, value in pairs.iteritems():
Utilisez ensuite object_hook
au lieu de 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'}}
L'utilisation de object_pairs_hook
résultats dans un dictionnaire de moins est instanciée pour chaque objet dans l'objet JSON, ce qui, si vous analysiez un document volumineux, pourrait valoir la peine.
str