Легко изменить формат объекта, который не является сериализуемым JSON, например, datetime.datetime.
Мое требование для целей отладки заключается в том, чтобы изменить способ расширения некоторых пользовательских объектов из базовых, таких как dict
и list
, получить сериализацию в формате json. Код:
import datetime
import json
def json_debug_handler(obj):
print("object received:")
print type(obj)
print("\n\n")
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 None
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 = "unprocessed"
test_json = { 'games' : games , 'scores' : scores , 'date': datetime.datetime.now() }
print(json.dumps(test_json,default=json_debug_handler))
if __name__ == '__main__':
test_debug_json()
DEMO: http://ideone.com/hQJnLy
Вывод:
{"date": "2013-05-07T01:03:13.098727", "games": ["mario", "contra", "tetris"], "scores": {"pk": 45, "dp": 10}}
Требуемый вывод:
{"date": "2013-05-07T01:03:13.098727", "games": { "orig": ["mario", "contra", "tetris"] ,"attrs" : { "src":"console"}} , "scores": { "orig": {"pk": 45, "dp": 10},"attrs":
"processed":"unprocessed }}
Не работает ли обработчик default
для сериализуемых объектов?
Если нет, как я могу переопределить это, не добавляя методы toJSON к расширенным классам?
Кроме того, есть версия JSON-кодировщика, которая не работает:
class JsonDebugEncoder(json.JSONEncoder):
def default(self,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 json.JSONEncoder.default(self, obj)
Если есть hack с pickle,__getstate__,__setstate__,
, а затем с помощью json.dumps над объектом pickle.loads, я также открыт для этого, я попытался, но это не сработало.