将Python的json.loads()对象钩子参数化为工厂方法
我现在正在写一个应用程序,使用Python的JSON模块,觉得把JSON数据转化成合适的Python对象会很不错。
下面的代码运行得很好。
Class MyClass :
def __init__(self, argA = None, argB = None, ... , JSON_Object=None):
self.attrA = argA
self.attrB = argB
...
if JSON_Object :
self.attrA = json.loads(JSON_Object, object_hook=self._getAttributeA)
self.attrB = json.loads(JSON_Object, object_hook=self._getAttributeB)
...
# Individual call back functions for the init... *yucky*.
def _getAttributeA(self, JSON_Object) :
if 'attrA' in JSON_Object :
return JSON_Object['attrA']
def _getAttributeB(self, JSON_Object) :
if 'attrB' in JSON_Object :
return JSON_Object['attrB']
...
不过,当属性超过五个的时候,每个属性都要重新写函数就有点烦人了。考虑到这里其实可以用工厂方法来解决,所需的只不过是一些参数。
我该怎么模拟这个呢?
我多次查看了Python的JSON文档,但我很沮丧,为什么这个功能不是立刻就能实现的呢?
Class MyClass :
def __init__(self, argA=None, argB=None, ..., JSON_Object=None):
self.attrA = argA
self.attrB = argB
...
if JSON_Object :
self.attrA = json.loads(JSON_Object, object_hook=self._getAttribute, args=["attrA"])
self.attrB = json.loads(JSON_Object, object_hook=self._getAttribute, args=["arrtB"])
...
# super simple, general, parameterized callback function for json.loads()
def _getAttribute(self, JSON_Object, args) :
if args[0] in JSON_Object :
return JSON_Object[args[0]]
一个复杂的解决方案也可以,但更大的问题是,为什么这不能立刻实现呢??
1 个回答
1
你用object_hook
的方式真有点奇怪。object_hook
是用来定制反序列化过程的,目的是把字典转换成其他数据类型,而不是用来从JSON中读取字段。如果你只是想读取字段,应该直接用loads
来加载JSON,不用object_hook
,然后用普通的索引语法从得到的字典中读取字段:
data = json.loads(JSON_Object)
self.attrA = data['attrA']
self.attrB = data['attrB']
...
或者如果你想把所有字段都放到同名的对象属性里:
self.__dict__.update(json.loads(JSON_Object))
如果你想递归地应用这个,那时候用object_hook
就合适了:
class JSON_Namespace(object):
def __init__(self, data_dict):
self.__dict__.update(data_dict)
@classmethod
def load_from_json(cls, json_string):
return json.loads(json_string, object_hook=cls)