为什么python的json.loads / dumps往返有损?

时间:2017-06-12 19:15:07

标签: python json serialization

我使用python序列化python对象以将其存储在我的缓存中。对于此序列化,我使用json.dumps()并在将其从缓存中取出后对其进行反序列化,我使用json.loads()。我认为这次往返会没有任何麻烦。但正如你在下面看到的那样,它失败了。

>>> import json
>>> from collections import namedtuple
>>> x = {"hello": 1, "goodbye": 2}
>>> y = namedtuple('Struct', x.keys())(*x.values())
>>> y
Struct(goodbye=2, hello=1)

>>> json.loads(json.dumps(y))
[2, 1]           # <= I expected this to be the same value as y above!!

为什么这个json.dumps / load往返有损?我可以使用什么函数将此对象序列化为反序列化将保留其原始值?我尝试使用pickle但它无法序列化对象。

1 个答案:

答案 0 :(得分:3)

json尝试根据类型序列化对象。它不能序列化任何对象,只能序列化&#34; basic&#34;一些,例如tuple(转换为方括号,如list),dictlist ...(当然还有整数,字符串,浮点数)。

使用isinstance测试您的对象时,它会在tuple上成功,因为namedtuple旨在从tuple继承:

y = namedtuple('Struct', x.keys())(*x.values())
print(isinstance(y,tuple))

结果为True

因此,在encoder.py模块的json文件中,您的数据与isinstance方法中的iterencode测试相匹配(下面的代码提取,我的Python 3.4的第311行)版):

   if isinstance(value, (list, tuple)):
        chunks = _iterencode_list(value, _current_indent_level)

因此,从listtuple继承的任何类型都会被序列化为list

此处提出了解决方法:Serializing a Python namedtuple to json