如何在Python中创建自定义json反序列化器的图形

时间:2014-07-26 15:41:58

标签: python json

http://broadcast.oreilly.com/2009/05/pymotw-json.html提供了一个有用的介绍,使用钩子函数来控制如何将json对象映射到特定的python类。

对我来说,如何将其扩展到更深层的图表并不明显。考虑类似的事情:

{
  "list_of_x": {
      "type": "x",
      "items" : [
        { "key" : "value" },
        { "key" : "value" }
      ]
  }
}

我想使用JSONDecoderobject_hook将外部对象映射到一个python类,将列表中的内部对象映射到另一个python类。当钩子被叫到'下面'时,如何看到上面type插槽的值?或者,如果没有类型,因为只有一种类型,我怎么知道我在哪里使用它?

1 个答案:

答案 0 :(得分:1)

只要JSON对象关闭,object_hook就会被称为 ,所以遇到}字符时。

因此,首先为最深层嵌套的对象调用object_hook。对于您的示例,它将被调用:

  1. { "key" : "value" }列表
  2. 中的第一个items
  3. { "key" : "value" }列表
  4. 中的第二个items
  5. 包含list_of_xtype键的items对象。
  6. 包含list_of_x密钥的最外层对象。
  7. 因为尚未解析外部对象,所以除了到目前为止已解析的内容之外没有其他上下文;在第一次和第二次调用时,您{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'}}