Die Antwort von Mike Brennan ist knapp, aber es gibt keinen Grund, die gesamte Struktur erneut zu durchqueren. Wenn Sie den object_hook_pairs
Parameter (Python 2.7+) verwenden:
object_pairs_hook
ist eine optionale Funktion, die mit dem Ergebnis eines Objektliteral aufgerufen wird, das mit einer geordneten Liste von Paaren dekodiert wurde. Der Rückgabewert von object_pairs_hook
wird anstelle von verwendet dict
. Diese Funktion kann verwendet werden, um benutzerdefinierte Decoder zu implementieren, die von der Reihenfolge abhängen, in der die Schlüssel- und Wertepaare decodiert werden (wobei beispielsweise collections.OrderedDict
die Reihenfolge des Einfügens gespeichert wird). Wenn object_hook
auch definiert, hat das object_pairs_hook
Priorität.
Damit erhalten Sie jedes JSON-Objekt, sodass Sie die Dekodierung ohne Rekursion durchführen können:
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'}}
Beachten Sie, dass ich den Hook nie rekursiv aufrufen muss, da jedes Objekt an den Hook übergeben wird, wenn Sie den verwenden object_pairs_hook
. Sie müssen sich um Listen kümmern, aber wie Sie sehen können, wird ein Objekt in einer Liste ordnungsgemäß konvertiert, und Sie müssen nicht rekursiv arbeiten, um dies zu erreichen.
EDIT: Ein Mitarbeiter wies darauf hin, dass Python2.6 nicht hat object_hook_pairs
. Sie können diesen Python2.6 weiterhin verwenden, indem Sie eine sehr kleine Änderung vornehmen. Ändern Sie im Haken oben:
for key, value in pairs:
zu
for key, value in pairs.iteritems():
Dann verwenden Sie object_hook
anstelle von 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'}}
Wenn Sie object_pairs_hook
Ergebnisse verwenden, wird für jedes Objekt im JSON-Objekt ein Wörterbuch weniger instanziiert. Wenn Sie ein großes Dokument analysieren, lohnt sich dies möglicherweise.
str