首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Pythonic json序列化

Pythonic json序列化
EN

Stack Overflow用户
提问于 2013-08-07 08:28:24
回答 4查看 347关注 0票数 3

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

然而,它并不能很好地执行到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\"}"]

这是我使用的代码:

代码语言:javascript
复制
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

当python对象包含项目列表时,您是否可以建议一种更复杂的方式来执行json序列化?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-08-07 09:11:11

结合njzk2 2和freakish的答案,我得到了一个很好的解决方案。

代码语言:javascript
复制
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"}],就像我所需要的那样。

票数 2
EN

Stack Overflow用户

发布于 2013-08-07 08:36:30

实际上,解决这一问题的唯一有效方法是一些丑陋的,而IMHO则是非丙酮的。

解决方案是扩展JSONEncoder,重写其default()方法:

代码语言:javascript
复制
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)
票数 2
EN

Stack Overflow用户

发布于 2013-08-07 08:36:10

问题是您要序列化两次。一次在x.to_json()中,第二次当您创建一个列表并在Tasks.to_json中序列化它。我建议您转换为dicts而不是JSON:

代码语言:javascript
复制
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类的实例时:

代码语言:javascript
复制
TasksInstance = Tasks()
json.dumps(TasksInstance.to_serializable())

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18098369

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档