Câu trả lời của Mike Brennan rất gần, nhưng không có lý do gì để duyệt lại toàn bộ cấu trúc. Nếu bạn sử dụng tham số object_hook_pairs
(Python 2.7+):
object_pairs_hook
là một hàm tùy chọn sẽ được gọi với kết quả của bất kỳ đối tượng nào được giải mã theo nghĩa đen với một danh sách các cặp theo thứ tự. Giá trị trả về của object_pairs_hook
sẽ được sử dụng thay vì dict
. Tính năng này có thể được sử dụng để thực hiện các bộ giải mã tùy chỉnh dựa trên thứ tự các cặp khóa và giá trị được giải mã (ví dụ: collections.OrderedDict
sẽ ghi nhớ thứ tự chèn). Nếu object_hook
cũng được xác định, object_pairs_hook
ưu tiên.
Với nó, bạn nhận từng đối tượng JSON được trao cho bạn, do đó bạn có thể thực hiện giải mã mà không cần đệ quy:
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'}}
Lưu ý rằng tôi không bao giờ phải gọi hook một cách đệ quy vì mọi đối tượng sẽ được trao cho hook khi bạn sử dụng object_pairs_hook
. Bạn phải quan tâm đến danh sách, nhưng như bạn có thể thấy, một đối tượng trong danh sách sẽ được chuyển đổi chính xác và bạn không phải lặp lại để thực hiện điều đó.
EDIT: Một đồng nghiệp đã chỉ ra rằng Python2.6 không có object_hook_pairs
. Bạn vẫn có thể sử dụng Python2.6 này bằng cách thực hiện một thay đổi rất nhỏ. Trong hook ở trên, thay đổi:
for key, value in pairs:
đến
for key, value in pairs.iteritems():
Sau đó sử dụng object_hook
thay vì 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'}}
Sử dụng object_pairs_hook
kết quả trong một từ điển ít hơn được khởi tạo cho từng đối tượng trong đối tượng JSON, nếu bạn đang phân tích một tài liệu khổng lồ, có thể có giá trị trong khi.
str