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

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

该类是一个简单的类,其字段只有整数、字符串和 float ,并从一个父父类(super class)继承类似的字段,例如:

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 方法是最好的方法吗?最后,拥有引用另一个对象的字段是否会使事情变得非常复杂?如果是这样,我可以重写我的代码,只在类中包含简单的字段(如字符串/ float 等)

谢谢。

最佳答案

我过去曾使用过这种策略并且对此非常满意:将您的自定义对象编码为 JSON 对象文字(如 Python dicts),其结构如下:

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

很容易扩展编码器和解码器以支持自定义类型(例如 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}
        }
    }
}

https://stackoverflow.com/questions/2343535/

相关文章:

java - 如何在 Java 的 JSON 字符串中找到指定的名称及其值?

json - 在jq中将字符串转换为json

javascript - 在 HTML 数据属性上添加 JSON 是不是很糟糕?

ios - 如何在 Swift 中解析 JSON 中的数组?

javascript - 如何使用 Javascript 将数据写入 JSON 文件

json - 自定义 MarshalJSON() 永远不会在 Go 中被调用

javascript - 短语对象文字表示法中的 "literal"是什么意思?

json - Golang 将 JSON 数组解析成数据结构

c# - 如何使用 Newtonsoft.Json 包在 C#(4.0) 中解析我的 json 字符

ios - (Cocoa 错误 3840。)“(字符 0 周围的值无效。)AFNetworking