使用object_hook将JSON dicts解析为对象的奇怪行为

时间:2011-02-04 06:13:35

标签: python json

我一直是exploring the json library,我正在尝试将对象转换为JSON数据并再次返回。我在运行此示例代码时遇到了麻烦:

import json

class Obj:
    '''
    classdocs
    '''

    def __init__(self,s,hello="Hello world!"):
        '''
        Constructor
        '''
        self.s = s
        self.hello = hello
    def __repr__(self):
        return '<MyObj(%s,%s)>' % (self.s, self.hello)

def objToJSON(obj):
    return obj.__dict__

def jSONToObj(json):
    print(json)
    return Obj(**json)

if __name__ == '__main__':
    str = json.dumps(Obj("Hello","World"), default=objToJSON, sort_keys=True)
    print(str)
    print(json.loads(str,object_hook=jSONToObj))
    str = json.dumps(Obj("Text",{"a":"aaaa","b":"BBBBB","C":"ccccc"}), default=objToJSON, sort_keys=True)
    print(str)
    print(json.loads(str,object_hook=jSONToObj))

其输出为:

{"hello": "World", "s": "Hello"}
{'s': 'Hello', 'hello': 'World'}
<MyObj(Hello,World)>
{"hello": {"C": "ccccc", "a": "aaaa", "b": "BBBBB"}, "s": "Text"}
{'a': 'aaaa', 'C': 'ccccc', 'b': 'BBBBB'}
Traceback (most recent call last):
  File "C:\Users\dimo414\src\test.py", line 27, in <module>
    print(json.loads(str,object_hook=jSONToObj))
  File "C:\Python31\lib\json\__init__.py", line 318, in loads
    return cls(**kw).decode(s)
  File "C:\Python31\lib\json\decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Python31\lib\json\decoder.py", line 355, in raw_decode
    obj, end = self.scan_once(s, idx)
  File "C:\Users\dimo414\src\test.py", line 22, in jSONToObj
    return Obj(**json)
TypeError: __init__() got an unexpected keyword argument 'a'

似乎当字典是对象字典中的值时,传递给jSONToObj的数据是内部字典,而不是完整字典。那是为什么?

1 个答案:

答案 0 :(得分:3)

由于您指定应使用函数jSONToObj重建对象,因此反序列化器假定所有dicts都是对象并尝试在其上调用反序列化器。

来自文档:

  

object_hook是一个可选功能   将被调用的结果   任何对象文字解码(一个字典)。   object_hook的返回值将是   用来代替字典。这个   功能可用于实现   自定义解码器(例如JSON-RPC类   提示)。

内部字典是第一个被反序列化的,可能是因为loads以递归方式工作并从底层开始。在反序列化对象之前,必须反序列化其参数。