2013-08-07 65 views
3

我試圖有一個體面的業務層是服務器端。每個新業務類別可能存儲在數據庫中的工作量較少。pythonic json序列化

但是,它不能很好地執行轉換爲json。它適用於簡單的python對象,使用json.dumps(self.__dict__)。但是一個簡單的python對象列表並沒有很好地序列化爲json。

當執行列表我嘗試return json.dumps([x.to_json() for x in self.my_list_items])的JSON序列化,但它輸出其它附加雙引號,和\」列表中的每個項目:["{\"completed\": 0, \"id\": 1, \"name\": \"labelOne\"}", "{\"completed\": 0, \"id\": 2, \"name\": \"Label2\"}"]

這是我使用的代碼:

class JSONizable(object): 
    def to_json(self): 
     return json.dumps(self.__dict__)  

class Task(JSONizable): 
    def __init__(self): 
     self.id = -1 
     self.name = "new task" 
     self.completed = 1 

    def load_sql(self, sql): 
     #do things 

class Tasks(JSONizable): 
    def __init__(self): 
     self.tasks=[] 

    def load_sql(self,sql): 
     #do things 

    def to_json(self): 
     return json.dumps([x.to_json() for x in self.tasks]) # things go bad here 

你可以建議進行JSON序列化的Python對象更Python的方式,當這樣的對象包含的項目列表?

+0

您正在編碼爲JOSN,然後轉儲JSON。我想你只是想:'返回json.dumps(self.tasks)' – ckhan

+0

@ckhan,如果我這樣做,json模塊宣稱這個任務不是json序列化的。 –

+0

查看編寫自定義JSON編碼器的文檔:http://docs.python.org/2/library/json.html#json.JSONEncoder – ckhan

回答

1

的問題是,你是在序列化的兩倍。一旦,第二次創建列表並將其序列化爲Tasks.to_json。我建議你轉換爲類型的字典而不是JSON:

class Task(JSONizable): 
    def to_serializable(self): 
     return { 
      # some JSON serializable data here 
      "id": self.id, 
      "name": self.name, 
      "completed": self.completed 
     } 

class Tasks(JSONizable): 
    def to_serializable(self): 
     return [x.to_serializable() for x in self.tasks] 

,然後當你有Tasks類的一個實例:

TasksInstance = Tasks() 
json.dumps(TasksInstance.to_serializable()) 

順便說一句:使用self.__dict__可能不反正工作,因爲實例JSONizable可能包含不可序列化的屬性,例如另一個類的實例。

2

其實唯一的工作解決方案是有點醜陋和恕我直言unpythonic。

的解決方案是延伸JSONEncoder重寫其default()方法:

import json 

class CustomEncoder(json.JSONEncoder): 
    def default(self, obj): 
     if not isinstance(obj, Task): 
      return super(CustomEncoder, self).default(obj) 
     return obj.__dict__ 

json.dumps(list_of_tasks, cls=CustomEncoder) 
1

to_json格式爲json。返回__dict__足夠:

class JSONizable(object): 
    def to_json(self): 
     return self.__dict__ 
1

結合njzk2的與畸形的答案,我結束了與很好地做這項工作的解決方案。

import json 
import database 

class JSONizable(object): 
    def to_json(self): 
     return json.dumps(self.to_serializable()) 
    def to_serializable(self): 
     return self.__dict__ 

class Task(JSONizable): 
    def __init__(self): 
     self.id = -1 
     self.name = "new task" 
     self.completed = 1 

    def load_sql(self, sql): 
     #... 

class Tasks(JSONizable): 
    def __init__(self): 
     self.tasks=[] 

    def load_sql(self,sql): 
     #... 

    def to_serializable(self): 
     return [x.to_serializable() for x in self.tasks] 

def get_json_tasks(): 
    db = database.db 
    tasks = Tasks() 
    tasks.load_sql(db.get_sql_tasks()) 
    return tasks.to_json() 

它將輸出正確的JSON格式: [{"completed": 0, "id": 1, "name": "labelOne"}, {"completed": 0, "id": 2, "name": "labelTwo"}, {"completed": 0, "id": 3, "name": "LabelThree"}]就像我需要的。

+0

+1:好主意。只要注意'self .__ dict__'。它可能不是可序列化的。 – freakish

+0

是的,它只能用於簡單的扁平python對象。 –