我正在尝试将JSON解码为python对象。看了一些这里的样本/答案和其他网站,但似乎无法找到答案。
以下是代码:
import 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 ADecoder(json.JSONDecoder):
def decode (self, json_string):
default_obj = super(A, self).decode(json_string)
a_obj = A(default_obj['n'], default_obj['a'])
return a_obj
class BDecoder(json.JSONDecoder):
def decode (self, json_string):
default_obj = super(BDecoder, self).decode(json_string)
#The problem with the code above is that here listOfA is a list of
#generic python objects.
b_obj = B(default_obj['b'], [default_obj['listOfA']])
return b_obj
以下是JSON示例
{
"b": "b",
"listOfA": [
{
"a": "a1",
"n": "n1"
},
{
"a": "a2",
"n": "n2"
}
],
}
我还试着看看是否可以将listOfA重新转换回字符串,然后再调用ADecoder。例如:
aDecoder = ADecoder()
b_obj = B(default_obj['b'], [aDecoder.decode(x.__str__()) for x in default_obj['servers']])
首先这不起作用,因为Python不知道如何将我的对象转换为(JSON)字符串,但即使它执行上述操作也会非常低效。
有关如何解决问题的任何建议?有没有办法在Python将JSON字符串转换为通用对象之前注入我的ADecoder?尝试查看示例,教程等,似乎无法找到这种情况。
答案 0 :(得分:2)
您必须从地图列表中重建listOfA
作为列表理解:
class BDecoder(json.JSONDecoder):
def decode (self, json_string):
default_obj = super(BDecoder, self).decode(json_string)
b_obj = B(default_obj['b'], [A(x['n'], x['a']) for x in default_obj['listOfA'] ] )
return b_obj
请勿尝试在BDecoder中重复使用ADecoder。
但这种方法不具备可扩展性。如果您希望能够使用深层嵌套对象,则必须重构解码器:将json字符串传递给由列表和映射组成的对象只需执行一次,就像json.load(file)
或{{一样简单1}}。但是,将这些地图转换为对象必须多次完成:这是必须明确编码的部分。
由于你的例子很简单,我只是在A和B类中使用静态方法:
json.loads(string)
这样你就可以更进一步:
class A:
def __init__ (self, n, a):
self.n = n
self.a = a
@staticmethod
def decode(jsonMap):
return A(jsonMap['n'], jsonMap['a'])
class B:
def __init__ (self, b, listOfA):
self.b = b
self.listOfA = list(listOfA)
@staticmethod
def decode(jsonMap):
return B(jsonMap['b'], [ A.decode(x) for x in jsonMap['listOfA'] ])