I want to encode objects in JSON. But, I can not figure out how to make the output without the string escaping.
import json
class Abc:
def __init__(self):
self.name="abc name"
def toJSON(self):
return json.dumps(self.__dict__, cls=ComplexEncoder)
class Doc:
def __init__(self):
self.abc=Abc()
def toJSON(self):
return json.dumps(self.__dict__, cls=ComplexEncoder)
class ComplexEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Abc) or isinstance(obj, Doc):
return obj.toJSON()
else:
return json.JSONEncoder.default(self, obj)
doc=Doc()
print doc.toJSON()
The result is (the dumps returns a string representation, that's why the " are escaped)
{"abc": "{\"name\": \"abc name\"}"}
I want something a little bit different. The expected result is
{"abc": {"name": "abc name"}"}
But I don't see how to... Any hint ?
thanks in advance.
my previous sample, with another nested object and your advices :
produces the expected result :
Thanks.
To avoid repetition of code like in Fred Laurent's answer I overloaded the
__iter__()
method as follows. This also permits to 'jsonize' list elements, datetime and decimal with no extra dependencies, just use dict().The output:
Hope it helps! Thanks
So, the immediate problem is that you're passing the json module a JSON value, which will get encoded as just another string in the JSON value.
The broader problem is that you're greatly overcomplicating this.
Drawing on JSON datetime between Python and JavaScript, I'd go with something closer to this:
which gets you:
This can be made cleaner/saner/safer (in particular, just grabbing
__dict__
isn't generally a recommended thing to do outside debugging/troubleshooting), but it should get the point across. All you need, fundamentally, is a way to get a json-compatible object (whether that's a simple string or number, or a list or dict) out of each "node" in the tree. That object should not be an already-JSON-serialized object, which is what you were doing.This is what you're looking for: https://github.com/jsonpickle/jsonpickle
It does nested serialization of Python objects and can easily be extended to serialize custom types.
I could not add this as a comment and adding as answer. Fred's final sample was useful for me.I was told jsonpickle does this, but could not get the module to install and run properly. So used the code here. Minor tweak though, I had way too many variables to add by hand to some of the objects. So this little loop simplified things:
It can be used in any object that has a subclass that is too busy to hand encode. Or can be made a helper for all classes. This also works for the full JSON presentation of member arrays that contain other classes (as long as they implement reprJSON() of course).