首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >来自json.dumps的怪异的json.dumps

来自json.dumps的怪异的json.dumps
EN

Stack Overflow用户
提问于 2014-09-15 14:00:16
回答 2查看 1.8K关注 0票数 3

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

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

这会失败(堆栈跟踪不是来自这个特定的代码片段,而是来自我的更大的脚本,我不会在这里粘贴,但本质上是相同的):

代码语言:javascript
运行
复制
>>> 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

306x内部数据中的一个值。它不总是相同的数字,有时它是一个不同的数字包含在迪特,显然是因为一个词的无序性。

然而,这就像一种魅力:

代码语言:javascript
运行
复制
>>> 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()函数对它们的行为不同。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-15 14:18:26

原因是dict中的数字不是普通的python int,而是明显不受json编码器支持的numpy.in64s。

票数 3
EN

Stack Overflow用户

发布于 2014-09-15 15:13:36

正如您所看到的,numpy int64数据类型不能直接序列化为json:

代码语言:javascript
运行
复制
>>> 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整数--包括较长的整数--可以序列化和反序列化:

代码语言:javascript
运行
复制
>>> json.loads(json.dumps(2**123))==2**123
True

因此,使用numpy,您可以直接转换为Python数据结构,然后序列化:

代码语言:javascript
运行
复制
>>> jstr=json.dumps(a.tolist())
>>> b=np.array(json.loads(jstr))
>>> np.array_equal(a,b)
True
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25849850

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档