【问题标题】:Create a Python class that I can serialize into a nested JSON object创建一个可以序列化为嵌套 JSON 对象的 Python 类
【发布时间】:2012-09-16 04:02:03
【问题描述】:

我是 Python 类和 JSON 的初学者,我不确定我的方向是否正确。

基本上,我有一个 web 服务,它在 POST 正文中接受 JSON 请求,如下所示:

{ "item" : 
     {
     "thing" : "foo",
     "flag" : true,
     "language" : "en_us"
     },
   "numresults" : 3
}

我开始像这样为“项目”创建一个类:

class Item(object):
    def __init__:
        self.name = "item"

    @property
    def thing(self):
        return self.thing

    @thing.setter
    def thing(self, value):
        self.thing = value

    ...

所以,我的问题是:

  1. 我的方向是否正确?
  2. 如何将 Python 对象转换为 JSON 字符串?

我在 python 中找到了很多关于 JSON 的信息,我查看了 jsonpickle,但我似乎无法创建一个最终输出所需嵌套字典的类。

编辑: 感谢 Joran 的建议,我坚持使用属性的类并添加了这样的方法:

    def jsonify(self):
        return json.dumps({ "item" :  self.__dict__ }, indent=4)

而且效果很好。

感谢大家的帮助。

【问题讨论】:

标签: python json


【解决方案1】:

只需向您的类添加一个返回字典的方法

def jsonify(self):
    return { 'Class Whatever':{
              'data1':self.data1,
               'data2':self.data2,
               ...
                               }

     }

并在结果上调用您的 tojson 函数...或在返回之前调用它以仅返回一个 json 结果...

【讨论】:

    【解决方案2】:

    看看colander project;它让您可以定义一个面向对象的“模式”,该模式很容易与 JSON 进行序列化。

    import colander
    
    class Item(colander.MappingSchema):
        thing = colander.SchemaNode(colander.String(),
                                    validator=colander.OneOf(['foo', 'bar']))
        flag = colander.SchemaNode(colander.Boolean())
        language = colander.SchemaNode(colander.String()
                                       validator=colander.OneOf(supported_languages)
    
    class Items(colander.SequenceSchema):
        item = Item()
    

    然后从 JSON 加载这些:

    items = Items().deserialize(json.loads(jsondata))
    

    colander 为您验证数据,返回一组 Python 对象,然后可以对其进行操作。

    或者,您必须创建特定的每个对象处理才能将 Python 对象转换为 JSON 结构,反之亦然。

    【讨论】:

      【解决方案3】:

      滤锅和 dict 建议都很棒。

      我只想补充一点,您应该退后一步,决定如何使用这些对象。
      这种通用方法的一个潜在问题是您需要一个列表或函数或其他映射来决定导出哪些属性。 (您可以在滤锅定义和 jsonify 定义中看到这一点)。

      您可能想要这种行为 - 或者您可能不想要。

      以 sqlalchemy 项目为例,它具有使用字段名称定义的类,例如离子滤锅。 对象本身存储了大量与数据库和数据库连接相关的辅助数据。

      为了获取您关心的基础字段数据,您需要访问包装数据的私有内部字典,或查询映射列的类:

      def columns_as_dict(self):
          return dict((col.name, getattr(self, col.name)) for col in sqlalchemy_orm.class_mapper(self.__class__).mapped_table.c)
      

      我并不是要让这件事变得过于复杂——我只是想建议您仔细考虑一下您可能如何使用这些对象。如果您只想从您放入的对象中获取相同的信息 - 那么一个简单的解决方案就可以了。但如果这些对象将包含其他类型的“私有”数据,您可能需要在不同类型的信息之间保持一些区别。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-12-29
        • 2020-10-03
        • 2021-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多