在python 3.4.0中,使用json.dumps()
在一个案例中抛出了一个TypeError,但在其他情况下就像魅力一样(我认为它等同于第一个)。
我有一个字典,其中键是字符串,值是数字和其他字符串(即类似{'x': 1.234, 'y': -5.678, 'z': {'a': 4, 'b': 0, 'c': -6}}
)。
这失败了(堆栈跟踪不是来自这个特定的代码片段,而是来自我的大脚本,我不会在这里粘贴,但它本质上是相同的):
>>> x = dict(foo()) # obtain the data and make a new dict of it to really be sure
>>> import json
>>> json.dumps(x)
Traceback (most recent call last):
File "/mnt/data/gandalv/progs/pycharm-3.4/helpers/pydev/pydevd.py", line 1733, in <module>
debugger.run(setup['file'], None, None)
File "/mnt/data/gandalv/progs/pycharm-3.4/helpers/pydev/pydevd.py", line 1226, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "/mnt/data/gandalv/progs/pycharm-3.4/helpers/pydev/_pydev_execfile.py", line 38, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc) #execute the script
File "/mnt/data/gandalv/School/PhD/Other work/Krachy/code/recalculate.py", line 54, in <module>
ls[1] = json.dumps(f)
File "/usr/lib/python3.4/json/__init__.py", line 230, in dumps
return _default_encoder.encode(obj)
File "/usr/lib/python3.4/json/encoder.py", line 192, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python3.4/json/encoder.py", line 250, in iterencode
return _iterencode(o, 0)
File "/usr/lib/python3.4/json/encoder.py", line 173, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: 306 is not JSON serializable
306
是x
中其中一个内部词汇中的值之一。它并不总是相同的数字,有时它是字典中包含的不同数字,显然是因为字典的无序性。
然而,这就像一个魅力:
>>> x = foo() # obtain the data and make a new dict of it to really be sure
>>> import ast
>>> import json
>>> x2 = ast.literal_eval(repr(x))
>>> x == x2
True
>>> json.dumps(x2)
"{...}" # the json representation of dict as it should be
请有人告诉我为什么会发生这种情况或可能是什么原因?最令人困惑的部分是这两个词组(原始词和通过评估原始词的表示获得的词)是相同的,但dumps()
函数对每个词的行为都不同。
答案 0 :(得分:3)
原因是dict
内的数字不是普通的python int
,而是numpy.in64
,而json编码器显然不支持这些数字。
答案 1 :(得分:1)
如您所见,numpy int64数据类型无法直接序列化为json:
>>> import numpy as np
>>> import json
>>> a=np.zeros(3, dtype=np.int64)
>>> a[0]=-9223372036854775808
>>> a[2]=9223372036854775807
>>> jstr=json.dumps(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/json/__init__.py", line 230, in dumps
return _default_encoder.encode(obj)
File "/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/json/encoder.py", line 192, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/json/encoder.py", line 250, in iterencode
return _iterencode(o, 0)
File "/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/json/encoder.py", line 173, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: array([-9223372036854775808, 0, 9223372036854775807]) is not JSON serializable
但是,Python整数 - 包括更长的整数 - 可以序列化和反序列化:
>>> json.loads(json.dumps(2**123))==2**123
True
因此,使用numpy,您可以直接转换为Python数据结构,然后序列化:
>>> jstr=json.dumps(a.tolist())
>>> b=np.array(json.loads(jstr))
>>> np.array_equal(a,b)
True