如何将JSON数据写入文件?

如何将存储在字典data中的JSON数据写入文件?

f = open('data.json', 'wb')f.write(data)

这给出了错误:

TypeError:必须是字符串或缓冲区,而不是字典

2281336 次浏览

data是一个Python字典。在编写之前需要将其编码为JSON。

使用它来获得最大的兼容性(Python 2和3):

import jsonwith open('data.json', 'w') as f:json.dump(data, f)

在现代系统(即Python 3和UTF-8支持)上,您可以使用以下命令编写更好的文件:

import jsonwith open('data.json', 'w', encoding='utf-8') as f:json.dump(data, f, ensure_ascii=False, indent=4)

#0留档。

要获取utf8编码的文件,而不是在Python 2接受的答案中使用ascii编码的

import io, jsonwith io.open('data.txt', 'w', encoding='utf-8') as f:f.write(json.dumps(data, ensure_ascii=False))

Python 3中的代码更简单:

import jsonwith open('data.txt', 'w') as f:json.dump(data, f, ensure_ascii=False)

在Windows上,openencoding='utf-8'参数仍然是必要的。

要避免将数据的编码副本存储在内存中(dumps的结果)并在Python 2和3中输出utf8编码字节字符串,请使用:

import json, codecswith open('data.txt', 'wb') as f:json.dump(data, codecs.getwriter('utf-8')(f), ensure_ascii=False)

codecs.getwriter调用在Python 3中是多余的,但在Python 2中是必需的


可读性和大小:

使用ensure_ascii=False提供了更好的易读性和更小的尺寸:

>>> json.dumps({'price': '€10'})'{"price": "\\u20ac10"}'>>> json.dumps({'price': '€10'}, ensure_ascii=False)'{"price": "€10"}'
>>> len(json.dumps({'абвгд': 1}))37>>> len(json.dumps({'абвгд': 1}, ensure_ascii=False).encode('utf8'))17

通过向dumpdumps的参数添加标志indent=4, sort_keys=True(如恐龙66所建议)来进一步提高易读性。这样,您将在json文件中获得一个很好的缩进排序结构,但文件大小略大。

我会对上述答案进行轻微修改,那就是编写一个经过美化的JSON文件,人眼可以更好地阅读。为此,用4个空格字符将sort_keys传递为Trueindent,你就可以了。还要注意确保ascii代码不会写在你的JSON文件中:

with open('data.txt', 'w') as out_file:json.dump(json_data, out_file, sort_keys = True, indent = 4,ensure_ascii = False)

对于那些试图转储希腊语或其他“异国情调”语言(如我)但也遇到问题(Unicode错误)的奇怪字符,如和平符号(\u262E)或其他经常包含在json格式数据(如Twitter)中的人,解决方案可能如下(sort_keys显然是可选的):

import codecs, jsonwith codecs.open('data.json', 'w', 'utf8') as f:f.write(json.dumps(data, sort_keys = True, ensure_ascii=False))

使用JSONjson.dump()json.dumps()将数据写入文件。像这样写以将数据存储在文件中。

import jsondata = [1,2,3,4,5]with open('no.txt', 'w') as txtfile:json.dump(data, txtfile)

列表中的此示例存储到文件中。

我没有足够的声誉来添加评论,所以我只是在这里写下我对这个烦人的TypeError的一些发现:

基本上,我认为它只是Python2json.dump()函数的bug-它不能转储包含非ASCII字符的Python(字典/列表)数据,甚至你用encoding = 'utf-8'参数打开文件。(即无论你做什么)。但是,json.dumps()适用于Python 2和3。

为了说明这一点,继续phihag的回答:如果data包含非ASCII字符,他回答中的代码在Python 2中中断,但TypeError: must be unicode, not str除外。(Python 2.7.6,Debian):

import jsondata = {u'\u0430\u0431\u0432\u0433\u0434': 1} #{u'абвгд': 1}with open('data.txt', 'w') as outfile:json.dump(data, outfile)

但是它在Python 3中运行良好。

json.dump(data, open('data.txt', 'wb'))

使用Python 2+3读写JSON文件;适用于Unicode

# -*- coding: utf-8 -*-import json
# Make it work for Python 2+3 and with Unicodeimport iotry:to_unicode = unicodeexcept NameError:to_unicode = str
# Define datadata = {'a list': [1, 42, 3.141, 1337, 'help', u'€'],'a string': 'bla','another dict': {'foo': 'bar','key': 'value','the answer': 42}}
# Write JSON filewith io.open('data.json', 'w', encoding='utf8') as outfile:str_ = json.dumps(data,indent=4, sort_keys=True,separators=(',', ': '), ensure_ascii=False)outfile.write(to_unicode(str_))
# Read JSON filewith open('data.json') as data_file:data_loaded = json.load(data_file)
print(data == data_loaded)

解释#0的参数:

  • indent:使用4个空格来缩进每个条目,例如当一个新字典开始时(否则所有字典都将在一行中),
  • sort_keys:对字典的键进行排序。如果您想使用diff工具比较json文件/将它们置于版本控制下,这很有用。
  • separators:防止Python添加尾随空格

带着一个包裹

看看我的实用程序包#0,一个超级简单和容易记住的:

import mpu.iodata = mpu.io.read('example.json')mpu.io.write('example.json', data)

创建JSON文件

{"a list":[1,42,3.141,1337,"help","€"],"a string":"bla","another dict":{"foo":"bar","key":"value","the answer":42}}

常见文件结尾

.json

替代品

对于您的应用程序,以下内容可能很重要:

  • 支持其他编程语言
  • 读/写性能
  • 紧凑性(文件大小)

另见:数据序列化格式的比较

如果您正在寻找一种创建配置文件的方法,您可能想阅读我的短文Python中的配置文件

如果您尝试使用json格式将熊猫数据框写入文件,我建议您这样做

destination='filepath'saveFile = open(destination, 'w')saveFile.write(df.to_json())saveFile.close()

前面所有的答案都是正确的,这里有一个非常简单的例子:

#! /usr/bin/env pythonimport json
def write_json():# create a dictionarystudent_data = {"students":[]}#create a listdata_holder = student_data["students"]# just a countercounter = 0#loop through if you have multiple items..while counter < 3:data_holder.append({'id':counter})data_holder.append({'room':counter})counter += 1#write the filefile_path='/tmp/student_data.json'with open(file_path, 'w') as outfile:print("writing file to: ",file_path)# HERE IS WHERE THE MAGIC HAPPENSjson.dump(student_data, outfile)outfile.close()print("done")
write_json()

在此处输入图片描述

接受的答案很好。但是,我在使用它时遇到了“不是json可序列化”错误。

这是我如何修复它open("file-name.json", 'w')作为输出:

output.write(str(response))

虽然它不是一个很好的修复,因为它创建的json文件不会有双引号,但如果您正在寻找快速和肮脏的,它会很棒。

可以将JSON数据写入文件,如下所示

hist1 = [{'val_loss': [0.5139984398465246],'val_acc': [0.8002029867684085],'loss': [0.593220705309384],'acc': [0.7687131817929321]},{'val_loss': [0.46456472964199463],'val_acc': [0.8173602046780344],'loss': [0.4932038113037539],'acc': [0.8063946213802453]}]

写入文件:

with open('text1.json', 'w') as f:json.dump(hist1, f)

要编写带有缩进的JSON,“漂亮的打印”:

import json
outfile = open('data.json')json.dump(data, outfile, indent=4)

此外,如果您需要调试格式不正确的JSON,并且想要有用的错误消息,请使用import simplejson库,而不是import json(函数应该相同)

这只是对json.dumps用法的额外提示(这不是问题的答案,而是那些必须转储numpy数据类型的人的技巧):

class NumpyEncoder(json.JSONEncoder):""" Special json encoder for np types """def default(self, obj):if isinstance(obj, (np.int_, np.intc, np.intp, np.int8,np.int16, np.int32, np.int64, np.uint8,np.uint16, np.uint32, np.uint64)):return int(obj)elif isinstance(obj, (np.float_, np.float16, np.float32,np.float64)):return float(obj)elif isinstance(obj, (np.ndarray,)):return obj.tolist()return json.JSONEncoder.default(self, obj)

import json
#print(json.dumps(my_data[:2], indent=4, cls=NumpyEncoder)))with open(my_dir+'/my_filename.json', 'w') as f:json.dumps(my_data, indent=4, cls=NumpyEncoder)))

        elif isinstance(obj, (np.ndarray,)):return obj.tolist()

        elif isinstance(obj, (np.ndarray,)):return str(obj)

        else:return str(obj)

import json
data = {"field1":{"a": 10,"b": 20,},"field2":{"c": 30,"d": 40,},}
json_data = json.dumps(json_data)

你也可以添加缩进到json数据看起来更漂亮。

json_data = json.dumps(json_data, indent=4)

如果您想在转换为json之前对键进行排序,

json_data = json.dumps(json_data, sort_keys=True)

您也可以使用这两者的组合。

请参考json留档了解更多功能

最后你可以写入一个json文件

f = open('data.json', 'wb')f.write(json_data)

对于喜欢单线的人(因此with语句不是一个选项),比留下悬空打开的文件描述符更干净的方法可以是使用pathlib中的write_text并执行如下操作:

pathlib.Path("data.txt").write_text(json.dumps(data))

在某些不允许语句的上下文中,这可能很方便,例如:

[pathlib.Path(f"data_{x}.json").write_text(json.dumps(x)) for x in [1, 2, 3]]

我并不是说它应该优先于with(而且它可能更慢),只是另一种选择。