2017-04-08 4 views
1

So habe ich die folgenden Objekte:Python: serialisiert Objekt json

import os 
import sys 
import json 

class ComplexEncoder(json.JSONEncoder): 
    def default(self, obj): 
     if isinstance(obj, P): 
      return json.dumps(obj.__dict__) 
     # Let the base class default method raise the TypeError 
     return json.JSONEncoder.default(self, obj) 

class P(object): 
    def __init__(self): 
     self.name = "Unknown" 
     self.id = 1 
     self.lst = [] 

    def showName(self): 
     print(self.name) 
     for item in self.lst: 
      item.showName() 

    def add(self, p): 
     self.lst.append(p) 

    def serialize(self): 
     return json.dumps(self, cls=ComplexEncoder) 

class PFirst(P): 
    def __init__(self): 
     P.__init__(self) 
     self.name = "First" 
     self.id = 2 

p1 = PFirst() 
p1.showName() 

p = P() 
p.add(p1) 
p.showName() 

print(p.serialize()) 

Ich möchte ein Json machen, die die Attribute des Objekts reprezents p aber ich die folgende Fehlermeldung:

TypeError: <__main__.PFirst object at 0x000002AA287F1438> is not JSON serializable 

Kann mir bitte jemand helfen?

Antwort

1
 return json.dumps(obj.__dict__) 

Sie rufen json.dumps mit dem Standard-Encoder wieder, was sicherlich nicht wissen, wie mit P Objekte zu behandeln. Wenn Sie json.dumps anrufen wollen, verwenden Sie:

 return json.dumps(obj.__dict__, cls=type(self)) 
#          ^~~~~~~~~~~~~~~~ 

jedoch! Wenn der Druck das Ergebnis sehen wir das Ergebnis doppelt codiert als String:

"{\"name\": \"Unknown\", \"id\": 1, \"lst\": [\"{\\\"name\\\": \\\"First\\\", \\\"id\\\": 2, \\\"lst\\\": []}\"]}" 

Wenn Sie das ComplexEncoder Beispiel überprüfen, und auch die documentation of default(), werden wir feststellen, dass es sollte ein „serialisierbares Objekt“ zurückzukehren, nicht die serialisierte Zeichenfolge. So sollten Sie wirklich schreiben:

class ComplexEncoder(json.JSONEncoder): 
    def default(self, obj): 
     if isinstance(obj, P): 
      return obj.__dict__   # <----- 
     return json.JSONEncoder.default(self, obj) 

Ausgang:

{"name": "Unknown", "id": 1, "lst": [{"name": "First", "id": 2, "lst": []}]} 
+0

Ja, es funktioniert. Vielen Dank –

Verwandte Themen