object_hook没有解决完整的json

时间:2016-07-06 22:23:31

标签: python json

我无法理解object_hook函数解析json.loads提供的json的方式。

请考虑以下事项:

import json

j = '{"key": "Program1",\
    "value": {"codes": [], "name": "John Doe", "cities": ["New York", "Houston"]}}'

class Humans:
    def __init__(self, source, codes, name, cities):
        self.source = source
        self.codes = codes
        self.name = name
        self.cities = cities

def as_Humans(dct):
    print(dct)
    source = dct['key']
    value = dct['value']
    codes = value['codes']
    name = value['name']
    cities = value['cities']
    return(Humans(source, codes, name, cities))


print(json.loads(j))
human = json.loads(j, object_hook = as_Humans)        
print(human.name)

当我运行此操作时,我收到以下错误:

{'key': 'Program1', 'value': {'name': 'John Doe', 'cities': ['New York', 'Houston'], 'codes': []}}
{'name': 'John Doe', 'cities': ['New York', 'Houston'], 'codes': []}
Traceback (most recent call last):
  File "stackoverflow.py", line 25, in <module>
    human = json.loads(j, object_hook = as_Humans)        
  File "/usr/lib/python3.4/json/__init__.py", line 331, in loads
    return cls(**kw).decode(s)
  File "/usr/lib/python3.4/json/decoder.py", line 343, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.4/json/decoder.py", line 359, in raw_decode
    obj, end = self.scan_once(s, idx)
  File "stackoverflow.py", line 16, in as_Humans
    source = dct['key']
KeyError: 'key'

显然这不符合我认为的方式:从钩子中的print(dct),我可以看到只有原始json的一部分被传递,并且因为那部分没有密钥& #34;键&#34;,好吧,我收到一个关键错误。

如果我修改它以便在json中只有{"codes": [], "name": "John Doe", "cities": ["New York", "Houston"]}(并相应地修改其他所有内容),它就可以工作。

有趣的是,如果json是'{"value": {"codes": [], "name": "John Doe", "cities": ["New York", "Houston"]}}',它会以相同的方式失败(关键错误&#34;值&#34;)。

我错过了什么?我的JSON字符串无效吗?是否可以在不首先调整json的情况下执行此操作?

1 个答案:

答案 0 :(得分:1)

object_hook适用于嵌套在json中的每个对象/ dict,从最深到最高。 所以首先向钩子提供{"codes": [], "name": "John Doe", "cities": ["New York", "Houston"]}

您的示例可以使用以下object_hook修复:

def as_humans(dct):
    if not 'key' in dct:
        print("IT'S A NOT HUMAN", dct)
        return dct
    print("IT'S A HUMAN", dct)
    source = dct['key']
    value = dct['value']
    codes = value['codes']
    name = value['name']
    cities = value['cities']
    return (Humans(source, codes, name, cities))

,输出将是:

{'value': {'cities': ['New York', 'Houston'], 'name': 'John Doe', 'codes': []}, 'key': 'Program1'}
IT'S A NOT HUMAN {'cities': ['New York', 'Houston'], 'name': 'John Doe', 'codes': []}
IT'S A HUMAN {'value': {'cities': ['New York', 'Houston'], 'name': 'John Doe', 'codes': []}, 'key': 'Program1'}
John Doe