2013-08-07 29 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对象。 –