Jak zmienić zachowanie kodowania json dla obiektu python serializowalnego?

Łatwo jest zmienić format obiektu, który nie jest serializowalny JSON, np. Datetime.datetime.

Moim wymaganiem, do celów debugowania, jest zmiana sposobu, w jaki niektóre niestandardowe obiekty są rozszerzone z bazowychdict ilist , uzyskaj serializację w formacie json. Kod :

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()
PRÓBNY :http://ideone.com/hQJnLy

Wydajność:

{"date": "2013-05-07T01:03:13.098727", "games": ["mario", "contra", "tetris"], "scores": {"pk": 45, "dp": 10}}

Pożądane wyjście:

{"date": "2013-05-07T01:03:13.098727", "games": { "orig": ["mario", "contra", "tetris"] ,"attrs" : { "src":"console"}} , "scores": { "orig": {"pk": 45, "dp": 10},"attrs": "processed":"unprocessed }}

Czy todefault handler nie działa dla obiektów serializowalnych? Jeśli nie, jak mogę to zmienić, bez dodawania do metod rozszerzonych JSON?

Ponadto istnieje ta wersja kodera JSON, która nie działa:

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)

Jeśli jest hackpickle,__getstate__,__setstate__,a następnie za pomocą obiektu json.dumps over pickle.loads jestem również otwarty na to, próbowałem, ale to nie zadziałało.

questionAnswers(13)

yourAnswerToTheQuestion