在python3.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
有谁能告诉我为什么会发生这种事,或者是什么原因?最令人困惑的部分是,这两个dicts (最初的dicts和通过对原始function的表示获得的dicts)是相等的,但是dumps()
函数对它们的行为不同。
发布于 2014-09-15 14:18:26
原因是dict
中的数字不是普通的python int
,而是明显不受json编码器支持的numpy.in64
s。
发布于 2014-09-15 15:13:36
正如您所看到的,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
https://stackoverflow.com/questions/25849850
复制相似问题