如何用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
使用这样的自定义编码器可以工作,但我必须引用私有映射属性:
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)

有更好/更干净的方法吗?我不想一个接一个地把听写重建成一个简单的听写。

最佳答案

通过对json子类化,然后对dict用于创建json对象字符串的方法进行猴子修补,可以欺骗dict相信它正在处理一个真正的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)

我已经在Python3.4上测试过了,如果您有不同版本的python,那么上面可能需要一些调整,比如将attrdict.items更改为attrdict.iteritems

关于python - 如何启用python的json包对attrdict.AttrDict对象进行编码?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25109143/

10-11 06:59