It is easy to change the format of an object which is not JSON serializable eg datetime.datetime.
My requirement, for debugging purposes, is to alter the way some cu
If you are able to change the way json.dumps
is called. You can do all the processing required before the JSON encoder gets his hands on it. This version does not use any kind of copying and will edit the structures in-place. You can add copy()
if required.
import datetime
import json
import collections
def json_debug_handler(obj):
print("object received:")
print type(obj)
print("\n\n")
if isinstance(obj, collections.Mapping):
for key, value in obj.iteritems():
if isinstance(value, (collections.Mapping, collections.MutableSequence)):
value = json_debug_handler(value)
obj[key] = convert(value)
elif isinstance(obj, collections.MutableSequence):
for index, value in enumerate(obj):
if isinstance(value, (collections.Mapping, collections.MutableSequence)):
value = json_debug_handler(value)
obj[index] = convert(value)
return obj
def convert(obj):
if isinstance(obj, datetime.datetime):
return obj.isoformat()
elif isinstance(obj,mDict):
return {'orig':obj , 'attrs': vars(obj)}
elif isinstance(obj,mList):
return {'orig':obj, 'attrs': vars(obj)}
else:
return obj
class mDict(dict):
pass
class mList(list):
pass
def test_debug_json():
games = mList(['mario','contra','tetris'])
games.src = 'console'
scores = mDict({'dp':10,'pk':45})
scores.processed = "qunprocessed"
test_json = { 'games' : games , 'scores' : scores , 'date': datetime.datetime.now() }
print(json.dumps(json_debug_handler(test_json)))
if __name__ == '__main__':
test_debug_json()
You call json_debug_handler
on the object you are serializing before passing it to the json.dumps
. With this pattern you could also easily reverse the changes and/or add extra conversion rules.
edit:
If you can't change how json.dumps
is called, you can always monkeypatch it to do what you want. Such as doing this:
json.dumps = lambda obj, *args, **kwargs: json.dumps(json_debug_handler(obj), *args, **kwargs)