Python 来自json.dumps的奇怪类型错误

Python 来自json.dumps的奇怪类型错误,python,json,python-3.x,numpy,dictionary,Python,Json,Python 3.x,Numpy,Dictionary,在Python3.4.0中,使用json.dumps()在一种情况下会抛出一个TypeError,但在另一种情况下会像一个符咒一样工作(我认为这相当于第一种情况) 我有一个dict,其中键是字符串,值是数字和其他dict(即类似于{'x':1.234,'y':-5.678,'z':{'a':4,'b':0,'c':-6}) 这失败了(stacktrace不是来自这个特定的代码片段,而是来自我的较大脚本,我不会在这里粘贴它,但它本质上是相同的): 谁能告诉我为什么会发生这种情况,或者是什么原因?最

在Python3.4.0中,使用
json.dumps()
在一种情况下会抛出一个TypeError,但在另一种情况下会像一个符咒一样工作(我认为这相当于第一种情况)

我有一个dict,其中键是字符串,值是数字和其他dict(即类似于
{'x':1.234,'y':-5.678,'z':{'a':4,'b':0,'c':-6}

这失败了(stacktrace不是来自这个特定的代码片段,而是来自我的较大脚本,我不会在这里粘贴它,但它本质上是相同的):


谁能告诉我为什么会发生这种情况,或者是什么原因?最令人困惑的是,这两个dict(原始dict和通过评估原始dict的表示而获得的dict)是相等的,但是
dumps()
函数对它们的行为各不相同。

原因是
dict
中的数字不是普通的python
int
s,而是
numpy。在64
s中,json编码器显然不支持这些数据类型。

如您所见,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
因此,使用numpy,您可以直接转换为Python数据结构,然后序列化:

>>> jstr=json.dumps(a.tolist())
>>> b=np.array(json.loads(jstr))
>>> np.array_equal(a,b)
True

您确定它是一个实际的整数,而不是其他对象的
repr
306
?JSON告诉您
306
值不是它支持的类型。它有一个看起来像整数的表示,这一事实在这里显然是误导性的,因为如果它真的只是一个整数,你就不会得到这个异常。你能告诉我们
类型(_306_值)
是什么吗?@jornsharpe@MartijnPieters它是
numpy.int64
,所以这似乎就是原因。我错了,谢谢!
>>> 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
>>> json.loads(json.dumps(2**123))==2**123
True
>>> jstr=json.dumps(a.tolist())
>>> b=np.array(json.loads(jstr))
>>> np.array_equal(a,b)
True