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
Along the lines of FastTurtle's suggestion, but requiring somewhat less code and much deeper monkeying, you can override isinstance itself, globally. This is probably Not A Good Idea, and may well break something. But it does work, in that it produces your required output, and it's quite simple.
First, before json is imported anywhere, monkey-patch the builtins module to replace isinstance with one that lies, just a little bit, and only in a specific context:
_original_isinstance = isinstance
def _isinstance(obj, class_or_tuple):
if '_make_iterencode' in globals():
if not _original_isinstance(class_or_tuple, tuple):
class_or_tuple = (class_or_tuple,)
for custom in mList, mDict:
if _original_isinstance(obj, custom):
return custom in class_or_tuple
return _original_isinstance(obj, class_or_tuple)
try:
import builtins # Python 3
except ImportError:
import __builtin__ as builtins # Python 2
builtins.isinstance = _isinstance
Then, create your custom encoder, implementing your custom serialization and forcing the use of _make_iterencode (since the c version won't be affected by the monkeypatching):
class CustomEncoder(json.JSONEncoder):
def iterencode(self, o, _one_shot = False):
return super(CustomEncoder, self).iterencode(o, _one_shot=False)
def default(self, obj):
if isinstance(obj, datetime.datetime):
return obj.isoformat()
elif isinstance(obj,mDict):
return {'orig':dict(obj) , 'attrs': vars(obj)}
elif isinstance(obj,mList):
return {'orig':list(obj), 'attrs': vars(obj)}
else:
return None
And that's really all there is to it! Output from Python 3 and Python 2 below.
Python 3.6.3 (default, Oct 10 2017, 21:06:48)
...
>>> from test import test_debug_json
>>> test_debug_json()
{"games": {"orig": ["mario", "contra", "tetris"], "attrs": {"src": "console"}}, "scores": {"orig": {"dp": 10, "pk": 45}, "attrs": {"processed": "unprocessed"}}, "date": "2018-01-27T13:56:15.666655"}
Python 2.7.13 (default, May 9 2017, 12:06:13)
...
>>> from test import test_debug_json
>>> test_debug_json()
{"date": "2018-01-27T13:57:04.681664", "games": {"attrs": {"src": "console"}, "orig": ["mario", "contra", "tetris"]}, "scores": {"attrs": {"processed": "unprocessed"}, "orig": {"pk": 45, "dp": 10}}}