Pythonic json序列化

时间:2013-08-07 08:28:24

标签: python json

我试图拥有一个体面的服务器端业务层。减少每个新业务类存储在数据库中的工作量。

然而,它并没有很好地执行转换为json。它适用于简单的python对象,使用json.dumps(self.__dict__)。但是一个简单的python对象列表并没有很好地序列化为json。

当执行列表的json序列化时,我尝试return json.dumps([x.to_json() for x in self.my_list_items])但是它输出了额外的双引号,并且“对于列表中的每个项目都是:["{\"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

当这样的对象包含项目列表时,你能建议一个更pythonic的方法来执行python对象的json序列化吗?

4 个答案:

答案 0 :(得分:2)

实际上唯一可行的解​​决方案是有点丑陋和恕我直言。

解决方案是扩展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 :(得分:1)

问题是你要两次序列化。进入x.to_json()后第二次创建列表并在Tasks.to_json中序列化。我建议你转换为dicts而不是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 class的实例时:

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

顺便说一句:使用self.__dict__可能无论如何都行不通,因为JSONizable的实例可能包含不可序列化的属性,例如另一个类的实例。

答案 2 :(得分:1)

您的to_json格式为json。返回__dict__就足够了:

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

答案 3 :(得分: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"}]就像我需要的那样。