I have been exploring the json library, and am attempting to convert an object into JSON data and back again. I have run into trouble running this example code:
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))
The output of which is:
{"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'
It seems that when a dictionary is a value in the object’s dictionary, the data passed to jSONToObj is the internal dictionary, not the full dictionary. Why is that?
Since you specified that objects should be reconstructed using the function
jSONToObj, the deserializer assumes that all dicts are to be objects and tries to call your deserializer on them.From the docs:
The inner dict is the first to be deserialized, probably because
loadsworks recursively and starts from the bottom layer. It makes sense that before deserializing an object, you have to deserialize its arguments.