Відповідь Майка Бреннана близька, але немає підстав повторно переходити всю структуру. Якщо ви використовуєте параметр 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
. Вам потрібно дбати про списки, але, як бачите, об’єкт у списку буде належним чином перетворений, і вам не доведеться повторюватися, щоб це відбулося.
EDIT: Співробітник зазначив, що 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