使用json.dumps()时出现MemoryError

6 投票
2 回答
17466 浏览
提问于 2025-04-18 09:55

我想知道在把一个大数组转换成JSON格式时,json.dump()json.dumps()哪个更高效。

能不能给我一个使用json.dump()的例子?

其实我正在做一个Python的CGI程序,它从MySQL数据库中获取大量数据,使用的是ORM框架SQLAlchemy。在用户触发一些处理后,我把最终的结果存储在一个数组里,最后再把它转换成JSON格式。

但是在转换成JSON时,我遇到了这个问题:

 print json.dumps({'success': True, 'data': data}) #data is my array

我得到了以下错误:

Traceback (most recent call last):
  File "C:/script/cgi/translate_parameters.py", line 617, in     <module>
f.write(json.dumps(mytab,default=dthandler,indent=4))
  File "C:\Python27\lib\json\__init__.py", line 250, in dumps
    sort_keys=sort_keys, **kw).encode(obj)
  File "C:\Python27\lib\json\encoder.py", line 209, in encode
    chunks = list(chunks)
MemoryError

所以,我猜想使用json.dump()来分块转换数据可能会更好。有没有什么想法可以实现这个?

或者除了使用json.dump()之外,还有其他的建议吗?

2 个回答

8

在使用 JSON 模块时,它会在写入之前把整个 JSON 字符串都放到内存里,这就是为什么会出现 MemoryError 的原因。

为了避免这个问题,可以使用 JSON.Encoder().iterencode()

with open(filepath, 'w') as f:
    for chunk in json.JSONEncoder().iterencode(object_to_encode):
        f.write(chunk)

不过要注意,这种方法通常会比较慢,因为它是分成很多小块来写,而不是一次性写完。


特殊情况:

我有一个 Python 对象,它是一个字典列表,像这样:

[
    { "prop": 1, "attr": 2 },
    { "prop": 3, "attr": 4 }
    # ...
]

我可以用 JSON.dumps() 来处理单个对象,但如果要处理整个列表,就会出现 MemoryError。为了加快写入速度,我手动打开文件并写入 JSON 的分隔符:

with open(filepath, 'w') as f:
    f.write('[')

    for obj in list_of_dicts[:-1]:
        json.dump(obj, f)
        f.write(',')

    json.dump(list_of_dicts[-1], f)
    f.write(']')

如果你事先知道你的 JSON 对象结构,可能可以用这种方法。但一般情况下,还是建议使用 JSON.Encoder().iterencode()

10

你可以简单地把

f.write(json.dumps(mytab,default=dthandler,indent=4))

替换成

json.dump(mytab, f, default=dthandler, indent=4)

这样就可以把数据“流式”写入文件了。

撰写回答