当前位置: 首页 > 面试题库 >

用simplejson序列化简单类对象的最简单方法?

白翰海
2023-03-14
问题内容

我正在尝试使用JSON(使用simplejson)序列化python对象列表,并收到以下错误:对象“不可JSON序列化”。

该类是一个简单的类,其字段只有整数,字符串和浮点数,并且从一个父超类继承相似的字段,例如:

class ParentClass:
  def __init__(self, foo):
     self.foo = foo

class ChildClass(ParentClass):
  def __init__(self, foo, bar):
     ParentClass.__init__(self, foo)
     self.bar = bar

bar1 = ChildClass(my_foo, my_bar)
bar2 = ChildClass(my_foo, my_bar)
my_list_of_objects = [bar1, bar2]
simplejson.dump(my_list_of_objects, my_filename)

foo,bar是我上面提到的简单类型。唯一棘手的事情是,ChildClass有时具有一个字段,该字段引用另一个对象(类型不是ParentClass或ChildClass)。

用simplejson将其序列化为json对象的最简单方法是什么?使它可序列化为字典是否足够?为ChildClass 简单地编写 dict
方法的最佳方法是吗?最后,拥有引用另一个对象的字段会使事情变得复杂吗?如果是这样,我可以将代码重写为仅在类中具有简单字段(例如字符串/浮点等)。

谢谢。


问题答案:

我过去曾经使用过这种策略,并且对此感到非常满意:dict使用以下结构将自定义对象编码为JSON对象文字(例如Python ):

{ '__ClassName__': { ... } }

从本质上讲,这是一个项目,dict其单键是一个特殊字符串,用于指定要编码的对象类型,并且其值是dict实例属性的。如果这样的话。

编码器和解码器的一个非常简单的实现(从我实际使用的代码简化)如下:

TYPES = { 'ParentClass': ParentClass,
          'ChildClass': ChildClass }


class CustomTypeEncoder(json.JSONEncoder):
    """A custom JSONEncoder class that knows how to encode core custom
    objects.

    Custom objects are encoded as JSON object literals (ie, dicts) with
    one key, '__TypeName__' where 'TypeName' is the actual name of the
    type to which the object belongs.  That single key maps to another
    object literal which is just the __dict__ of the object encoded."""

    def default(self, obj):
        if isinstance(obj, TYPES.values()):
            key = '__%s__' % obj.__class__.__name__
            return { key: obj.__dict__ }
        return json.JSONEncoder.default(self, obj)


def CustomTypeDecoder(dct):
    if len(dct) == 1:
        type_name, value = dct.items()[0]
        type_name = type_name.strip('_')
        if type_name in TYPES:
            return TYPES[type_name].from_dict(value)
    return dct

在此实现中,假设您要编码的对象将具有一个from_dict()类方法,该方法知道如何dict从JSON解码后的实例中重新创建实例。

扩展编码器和解码器以支持自定义类型(例如datetime对象)很容易。

EDIT
,以回答您的编辑:像这样的实现的好处是它将自动对TYPES映射中找到的任何对象的实例进行编码和解码。这意味着它将自动处理ChildClass,如下所示:

class ChildClass(object):
    def __init__(self):
        self.foo = 'foo'
        self.bar = 1.1
        self.parent = ParentClass(1)

这应该导致JSON如下所示:

{ '__ChildClass__': {
    'bar': 1.1,
    'foo': 'foo',
    'parent': {
        '__ParentClass__': {
            'foo': 1}
        }
    }
}


 类似资料:
  • 本文向大家介绍jQuery序列化表单成对象的简单实现,包括了jQuery序列化表单成对象的简单实现的使用技巧和注意事项,需要的朋友参考一下 在使用easyui的datagrid组件时,在查询时传递的查询参数是对象类型,为了方便,扩展了jquery中的序列化方法,调用该方法,可以将表单的所有数据序列化 具体使用: 以上这篇jQuery序列化表单成对象的简单实现就是小编分享给大家的全部内容了,希望能给

  • 但它返回一个id为空且产品为空的对象。当然,我不需要为这个简单的操作编写自定义的吗?

  • 问题内容: 我决定使用简单XML序列化,并且遇到了基本问题。我试图在这个小类中将类实例序列化为final字段: 教程显示了如何通过注册转换器来序列化第三方对象,如下所示: 适用于UUID的转换器非常简单: 但是,这种简单的代码对我不起作用,在引发带有UUID字段的序列化对象期间,抛出异常 java.util.UUID类的转换不支持 。 我已经尝试过一些与自定义类似的东西(教程中没有介绍)对我有用:

  • 问题内容: 现在,我有一个Java程序,其类当前为POJO,并存储在易失性内存中。这些必须坚持下去。据我了解,两个流行的选择是JDO和Java Persistence API。对于对SQL,Torque等了解甚少的人,这是向程序数据添加持久性的最简单方法? 问题答案: 序列化到文件系统的传统方法是使用Java序列化。但是,您需要在各处实现Serializable。 一个更简单的解决方案是使用XSt

  • 我只是想序列化和反序列化简单的不可变对象,不明白为什么我不能用Jackson来做 它会因异常而失败: 我知道答案应该很简单,但这是最常见的情况,应该从盒子里起作用,不是吗?

  • 问题内容: 我在PyQt中有一个带有功能的GUI 。容易想象,当新图像应添加到QListWidget中时被调用。为了检测文件夹中的新图像,我使用了with来检测文件夹中的文件更改,然后该线程直接调用。 出于线程安全的原因,这会产生不应在gui线程之外调用的警告。 使此线程安全的最佳和最简单的方法是什么?QThread?信号/插槽?QMetaObject.invokeMethod?我只需要从线程传递