So ändern Sie json-Kodierung Verhalten für python-Objekt serialisierbar?

Ist es einfach, ändern Sie das format von einem Objekt, das nicht als JSON serialisierbar z.B. datetime.datetime.

Meine Forderung, für debugging-Zwecke ist die Art und Weise ändern einige benutzerdefinierte Objekte erweitert, von der Basis wie dict und list , serialisiert im json-format . Code :

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

Ausgabe:

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

Gewünschte Ausgabe:

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

Macht die default - handler nicht für serialisierbare Objekte ?
Wenn nicht, wie kann ich das überschreiben, ohne das hinzufügen von toJSON Methoden, um die erweiterten Klassen ?

Außerdem gibt es diese version der JSON-encoder, der nicht funktioniert :

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)

Wenn es einen hack mit pickle,__getstate__,__setstate__,und dann mit json.dumps über Gurke.lädt Objekt , ich bin offen, wie gut, habe ich versucht , aber das hat nicht funktioniert.

  • Mit einer geeigneten Klasse mit einem __getstate()__ - Methode sollte funktionieren. Mehr: stackoverflow.com/q/12627949/139010
  • Für Unterklassen der dict und json finden Sie unter Überschreiben von verschachtelten JSON-Kodierung von geerbten Standard-unterstützt Objekte wie dict, list
  • Das ist äquivalent zum schreiben eines komplexen benutzerdefinierten encoder,ich hoffe, es sollte ein einfacher Weg, um wieder eine andere represntation der Objekt-Encoder wie json oder Gurke ?
  • Der default-handler nur aufgerufen wird, wird für Objekte, die es nicht serialisieren. Da Sie Erben von Objekten kann es zu serialisieren, wird es führen Sie es mit der Standard-Serialisierung. Aber ich hatte etwas ähnliches vor ein paar Tagen. Hier ist " mein Ansatz: stackoverflow.com/questions/16361223/...
  • pickle unterstützt die Zustand Haken (__getstate__ und Gefährten), aber json unterstützt nicht solche Methoden hilfreich.
  • Es klingt wie Sie wollen Bearbeiten Sie Ihre Daten wie in einem javascript-Objekt, bevor Sie es zu serialisieren. Vielleicht so etwas wie jsobject nützlich sein könnte für Sie. Das sieht aus wie es hat einen json-encoder und-decoder gebündelt.
  • Würden Sie die Lösungen mit 3rd-party-json-Bibliotheken, oder sind Sie gebunden an die stlib json Modul?
  • eine gut gepflegte 3rd-party-json-Bibliothek tun würde.

InformationsquelleAutor DhruvPathak | 2013-05-06
Schreibe einen Kommentar