python自定义JSON编码器/解码器无法按预期工作

时间:2015-08-04 03:15:45

标签: python json

我正在尝试编码/解码嵌套对象,我将嵌套对象列表作为字符串而不是JSON对象。

class A:
    def __init__ (self, n, a):
        self.n = n
        self.a = a

class B:
    def __init__ (self, b, listOfA):
        self.b = b
        self.listOfA = []
        for a in listOfA:
            self.listOfA.append(a)

class AEncoder:
    def default (self, obj):
        if isinstance (obj, A):
            return {
                'n' : obj.n
                'a' : obj.a
            }
        return json.JSONEncoder.default(self, obj)

class BEncoder:
    def default (self, obj):
        if isinstance (obj, B):
            return {
                'b' : obj.n
                'listOfA' : json.dumps(obj.listOfA, cls=AEncoder)
            }
        return json.JSONEncoder.default(self, obj)

listOfA = [A('n1', 'a1'), A('n2', 'a2')]
tmpB = B('b', listOfA)

对于对象A,它正常工作,因为它非常直接。 B I得到的输出是这样的:

{
    "b" : "b"
    "listOfA" : "[{\"n\" : \"n1\", \"a\" : \"a1\"}, {\"n\" : \"n2\", \"a\" : \"a2\"}]"
}

我错的任何想法?输出应该是这样的:

{
    "b" : "b"
    "listOfA" : [{"n" : "n1", "a" : "a1"}, {"n" : "n2", "a" : "a2"}]
}

1 个答案:

答案 0 :(得分:1)

您的代码中有一些拼写错误,字典中缺少逗号,而当您在BEncoder中表示obj.b时,您会引用obj.n.

除此之外,问题是您在BEncoder中使用json.dumps()。此方法返回格式正确的json 字符串。然后BEncoder看到这个字符串并认为你想要listOfA的值是一个字符串,然后应该为json正确编码,这样就可以逃避你看到的字符。

这是一个解决方案,它不是返回一个字符串,而是返回一个"可序列化的对象" (例如,列表,字典等),如编码器所需。它正在从AEncoder()返回的字典(可序列化)中构建一个列表(可序列化).default()。

{"b": "b", "listOfA": [{"a": "a1", "n": "n1"}, {"a": "a2", "n": "n2"}]}

输出:

{{1}}