我正在尝试使用 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 dict
s),其结构如下:
{ '__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 字符串中找到指定的名称及其值?
javascript - 在 HTML 数据属性上添加 JSON 是不是很糟糕?
ios - 如何在 Swift 中解析 JSON 中的数组?
javascript - 如何使用 Javascript 将数据写入 JSON 文件
json - 自定义 MarshalJSON() 永远不会在 Go 中被调用
javascript - 短语对象文字表示法中的 "literal"是什么意思?
json - Golang 将 JSON 数组解析成数据结构