我无法理解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的情况下执行此操作?
答案 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