http://broadcast.oreilly.com/2009/05/pymotw-json.html提供了一个有用的介绍,使用钩子函数来控制如何将json对象映射到特定的python类。
对我来说,如何将其扩展到更深层的图表并不明显。考虑类似的事情:
{
"list_of_x": {
"type": "x",
"items" : [
{ "key" : "value" },
{ "key" : "value" }
]
}
}
我想使用JSONDecoder
和object_hook
将外部对象映射到一个python类,将列表中的内部对象映射到另一个python类。当钩子被叫到'下面'时,如何看到上面type
插槽的值?或者,如果没有类型,因为只有一种类型,我怎么知道我在哪里使用它?
答案 0 :(得分:1)
只要JSON对象关闭,object_hook
就会被称为 ,所以遇到}
字符时。
因此,首先为最深层嵌套的对象调用object_hook
。对于您的示例,它将被调用:
{ "key" : "value" }
列表items
{ "key" : "value" }
列表items
list_of_x
和type
键的items
对象。list_of_x
密钥的最外层对象。因为尚未解析外部对象,所以除了到目前为止已解析的内容之外没有其他上下文;在第一次和第二次调用时,您仅将{u'key': u'value'}
视为object_hook
的参数。
在第3步和第4步中,传入的字典将具有嵌套的容器值,包括先前对object_hook
的调用返回的内容。
你可以在这里使用启发式方法;根据键或值的类型(只有字符串或其他容器),您仍然可以选择对象类型,但只需传入有限的上下文,就必须这样做。
演示:
>>> from pprint import pprint
>>> from itertools import count
>>> import json
>>> counter = count(1)
>>> def verbose_object_hook(dct):
... print 'Object #{}'.format(next(counter))
... pprint(dct)
... return dct
...
>>> sample = '''\
... {
... "list_of_x": {
... "type": "x",
... "items" : [
... { "key" : "value" },
... { "key" : "value" }
... ]
... }
... }
... '''
>>> json.loads(sample, object_hook=verbose_object_hook)
Object #1
{u'key': u'value'}
Object #2
{u'key': u'value'}
Object #3
{u'items': [{u'key': u'value'}, {u'key': u'value'}], u'type': u'x'}
Object #4
{u'list_of_x': {u'items': [{u'key': u'value'}, {u'key': u'value'}],
u'type': u'x'}}
{u'list_of_x': {u'items': [{u'key': u'value'}, {u'key': u'value'}], u'type': u'x'}}