[英]json.dumps TypeError on Python dict
实施以下类以提供可作为json编码字典通过网络传递的通用对象。 我实际上是想对dict(!)进行json编码,但是它不起作用。
我知道它可以与自定义编码器类一起使用,但是我不明白为什么在编码字典时有必要这样做。
有人可以解释TypeError或提供一种无需子类化JSONEncoder即可对此进行编码的方法吗?
这是不良行为。
>>> def tree(): return CustomDict(tree)
>>> d = tree()
>>> d['one']['test']['four'] = 19
>>> d.dict
{ 'one' : { 'test': {'four': 19}}}
>>> type(d.dict)
<type 'dict'>
>>> import json
>>> json.dumps(d.dict)
# stacktrace removed
TypeError: {'one': {'test': {'four': 19}}} is not JSON serializable
>>> normal_d = {'one': {'test': {'four': 19}}}
>>> type(normal_d)
<type 'dict'>
>>> json.dumps(normal_d)
"{'one': {'test': {'four': 19}}}"
>>> normal_d == d
True
我很希望能够做到以下几点
>>>> json.dumps(dict(d))
"{'one': {'test': {'four': 19}}}"
但是我将dict属性添加为“强制使用”(显然无效)。 现在,这是一个更大的谜。 这是CustomDict类的代码
class CustomDict(collections.MutableMapping):
"""
A defaultdict-like object that can also have properties and special methods
"""
def __init__(self, default_type=str, *args, **kwargs):
"""
instantiate as a default-dict (str if type not provided). Try to update
self with each arg, and then update self with kwargs.
@param default_type: the type of the default dict
@type default_type: type (or class)
"""
self._type = default_type
self._store = collections.defaultdict(default_type)
self._dict = {}
for arg in args:
if isinstance(arg, collections.MutableMapping):
self.update(arg)
self.update(kwargs)
@property
def dict(self):
return self._dict
def __contains__(self, key):
return key in self._store
def __len__(self):
return len(self._store)
def __iter__(self):
return iter(self._store)
def __getitem__(self, key):
self._dict[key] = self._store[key]
return self._store[key]
def __setitem__(self, key, val):
self._dict[key] = val
self._store[key] = val
def __delitem__(self, key):
del self._store[key]
def __str__(self):
return str(dict(self._store))
您实际上要使类型成为dict
的子类,而不是collections.MutableMapping
的子类。
甚至更好的是,直接使用collections.defaultdict
,它已经是dict
的子类,可以轻松用于实现树的“类型”:
from collections import defaultdict
def Tree():
return defaultdict(Tree)
tree = Tree()
示范:
>>> from collections import defaultdict
>>> def Tree():
... return defaultdict(Tree)
...
>>> tree = Tree()
>>> tree['one']['two'] = 'foobar'
>>> tree
defaultdict(<function Tree at 0x107f40e60>, {'one': defaultdict(<function Tree at 0x107f40e60>, {'two': 'foobar'})})
>>> import json
>>> json.dumps(tree)
'{"one": {"two": "foobar"}}'
如果必须添加自己的方法和行为,则可以将defaultdict
子类化并在此基础上构建:
class CustomDict(defaultdict):
pass
由于这仍然是dict
的子类,因此json
库将愉快地将其转换为JSON对象,而无需进行特殊处理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.