用simplejson序列化简单类对象的最简单方法? [英] Easiest way to serialize a simple class object with simplejson?

查看:265
本文介绍了用simplejson序列化简单类对象的最简单方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to serialize a list of python objects with JSON (using simplejson) and am getting the error that the object "is not JSON serializable".

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

The class is a simple class having fields that are only integers, strings, and floats, and inherits similar fields from one parent superclass, e.g.:

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).

where foo, bar are simple types like I mentioned above. The only tricky thing is that ChildClass sometimes has a field that refers to another object (of a type that is not ParentClass or ChildClass).

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

What is the easiest way to serialize this as a json object with simplejson? Is it sufficient to make it serializable as a dictionary? Is the best way to simply write a dict method for ChildClass? Finally, does having the field that refer to another object significantly complicate things? If so, I can rewrite my code to only have simple fields in classes (like strings/floats etc.)

谢谢.

推荐答案

我过去曾经使用过这种策略,对此非常满意:以下结构:

I've used this strategy in the past and been pretty happy with it: Encode your custom objects as JSON object literals (like Python dicts) with the following structure:

{ '__ClassName__': { ... } }

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

That's essentially a one-item dict whose single key is a special string that specifies what kind of object is encoded, and whose value is a dict of the instance's attributes. If that makes sense.

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

A very simple implementation of an encoder and a decoder (simplified from code I've actually used) is like so:

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()类方法,该方法知道如何根据从JSON解码的dict重新创建实例.

In this implementation assumes that the objects you're encoding will have a from_dict() class method that knows how to take recreate an instance from a dict decoded from JSON.

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

It's easy to expand the encoder and decoder to support custom types (e.g. datetime objects).

编辑,以回答您的这种实现的好处是,它将自动编码和解码在TYPES映射中找到的任何对象的实例.这意味着它将像这样自动处理ChildClass:

EDIT, to answer your edit: The nice thing about an implementation like this is that it will automatically encode and decode instances of any object found in the TYPES mapping. That means that it will automatically handle a ChildClass like so:

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

这将导致JSON如下所示:

That should result in JSON something like the following:

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

这篇关于用simplejson序列化简单类对象的最简单方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆