如何在json中编码AttrDict对象?
import sys, json, attrdict
ad = attrdict.AttrDict({'else': 1, 'inner': attrdict.AttrDict({'something': 2})})
json.dump(ad, sys.stdout)
此操作因TypeError: a{'something': 2} is not JSON serializable
使用像这样的自定义编码器,但我必须引用私有_mapping属性:
import sys, json, attrdict
class attrDictEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, attrdict.AttrDict):
return obj._mapping
return json.JSONEncoder.default(self, obj)
ad = attrdict.AttrDict({'else': 1, 'inner': attrdict.AttrDict({'something': 2})})
json.dump(ad, sys.stdout, cls=attrDictEncoder)
有更好/更清洁的方式吗?我不想将逐项重新构建的dicts重新构建成一个简单的dicts。
答案 0 :(得分:2)
你的代码非常接近。以下解决方案将函数传递给JSON编码器,该编码器将AttrDict
转换为普通字典。普通的JSON机器在找到非标准类型时调用它,如AttrDict
。
import json, attrdict
def as_attrdict(val):
if not isinstance(val, attrdict.AttrDict):
raise TypeError('not AttrDict')
return dict(val)
ad = attrdict.AttrDict({'else': 1,
'inner': attrdict.AttrDict({'something': 2})})
print json.dumps(ad, default=as_attrdict)
{"inner": {"something": 2}, "else": 1}
AttrDict是一个类似字典的对象,允许以元素和属性的形式访问其元素。
感谢user2357112简化代码。
答案 1 :(得分:1)
有可能欺骗json
相信它正在通过子类化dict
来处理真正的dict
,然后猴子修补json
用来创建json对象字符串的方法。这样我们就可以给json
一个只调用给定AttrDict
的相关方法的虚拟类。
def as_attrdict(val):
if not isinstance(val, AttrDict):
raise TypeError('not AttrDict')
return AttrDictForJson(val)
class AttrDictForJson(dict):
def __init__(self, attrdict):
super().__init__()
self.items = attrdict.items
self._len = attrdict.__len__
# key creation necessary for json.dump to work with CPython
# This is because optimised json bypasses __len__ on CPython
if self._len() != 0:
self[None] = None
def __len__(self):
return self._len()
用法:
json_string = dumps(attrdict, default=as_attrdict)
我在python 3.4上测试了这个,如果你有不同版本的python,那么上面的内容可能需要一些调整,例如将attrdict.items
更改为attrdict.iteritems
答案 2 :(得分:0)
如果您确定AttrDict对象中没有无效数据,则可以单线保存:
json.dumps(obj, default=dict)