如何将 JSON 数据写入文件?
- 2024-11-27 10:42:00
- admin 原创
- 13
问题描述:
如何将字典中存储的 JSON 数据写入data
文件?
f = open('data.json', 'wb')
f.write(data)
这会出现错误:
TypeError:必须是字符串或缓冲区,而不是字典
解决方案 1:
data
是一个Python字典,写入前需要编码为JSON。
使用这个来获得最大的兼容性(Python 2 和 3):
import json
with open('data.json', 'w') as f:
json.dump(data, f)
在现代系统(即 Python 3 和 UTF-8 支持)上,你可以使用以下命令编写更好的文件:
import json
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
查看json
文档。
解决方案 2:
要获取utf8编码的文件(而不是Python 2 接受的答案中的ascii编码的文件),请使用:
import io, json
with io.open('data.txt', 'w', encoding='utf-8') as f:
f.write(json.dumps(data, ensure_ascii=False))
在 Python 3 中代码更简单:
import json
with open('data.txt', 'w') as f:
json.dump(data, f, ensure_ascii=False)
在 Windows 上,encoding='utf-8'
参数open
仍然是必要的。
为了避免在内存中存储数据的编码副本(的结果)并在 Python 2 和 3 中dumps
输出utf8 编码的字节串,请使用:
import json, codecs
with 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
通过在或的参数中添加标志indent=4, sort_keys=True
(如dinos66所建议)来进一步提高可读性。 这样,您将在 json 文件中获得一个缩进良好的排序结构,但文件大小会稍大一些。dump
`dumps`
解决方案 3:
我会稍微修改上述答案,即编写一个美化的 JSON 文件,以便人眼可以更好地阅读。为此,传递sort_keys
为True
和indent
4 个空格字符,您就可以开始了。还要注意确保 ASCII 码不会写入您的 JSON 文件中:
with open('data.txt', 'w') as out_file:
json.dump(json_data, out_file, sort_keys = True, indent = 4,
ensure_ascii = False)
解决方案 4:
使用 Python 2+3 读取和写入 JSON 文件;适用于 unicode
# -*- coding: utf-8 -*-
import json
# Make it work for Python 2+3 and with Unicode
import io
try:
to_unicode = unicode
except NameError:
to_unicode = str
# Define data
data = {'a list': [1, 42, 3.141, 1337, 'help', u'€'],
'a string': 'bla',
'another dict': {'foo': 'bar',
'key': 'value',
'the answer': 42}}
# Write JSON file
with 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 file
with open('data.json') as data_file:
data_loaded = json.load(data_file)
print(data == data_loaded)
参数解释json.dump
:
indent
:使用 4 个空格缩进每个条目,例如当开始一个新的字典时(否则所有内容将在一行中),sort_keys
:对字典的键进行排序。如果你想用 diff 工具比较 json 文件/将它们置于版本控制之下,这很有用。separators
:为了防止 Python 添加尾随空格
带有包装
看一下我的实用程序包mpu
,它非常简单且易于记忆:
import mpu.io
data = 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
替代方案
CSV:超级简单格式(读写)
JSON:适合编写人类可读的数据;非常常用(读取和写入)
YAML:YAML 是 JSON 的超集,但更易于阅读(读写,JSON 和 YAML 的比较)
pickle:一种 Python 序列化格式(读写)
MessagePack(Python 包):更紧凑的表示(读取和写入)
HDF5(Python 包):适用于矩阵(读写)
XML:也存在 叹息 (读写)
对于您的应用程序,以下内容可能很重要:
其他编程语言的支持
读写性能
紧凑性(文件大小)
另请参阅:数据序列化格式比较
如果你正在寻找创建配置文件的方法,你可能需要阅读我的短文《Python 中的配置文件》
解决方案 5:
对于那些像我一样试图抛弃希腊语或其他“外来”语言但也遇到问题(unicode 错误)的人来说,例如和平符号(/u262E)或其他经常包含在 json 格式数据(如 Twitter 的)中的奇怪字符,解决方案可能如下(sort_keys 显然是可选的):
import codecs, json
with codecs.open('data.json', 'w', 'utf8') as f:
f.write(json.dumps(data, sort_keys = True, ensure_ascii=False))
解决方案 6:
我没有足够的声誉来添加评论,所以我只在这里写下我对这个烦人的 TypeError 的一些发现:
基本上,我认为这只是 Python 2json.dump()
中函数的一个错误- 它无法转储包含非 ASCII 字符的 Python(字典/列表)数据,即使您使用该参数打开文件也是如此。(即无论您做什么)。但是,它适用于 Python 2 和 3。encoding = 'utf-8'
`json.dumps()`
TypeError: must be unicode, not str
为了说明这一点,请跟进 phihag 的回答:如果data
包含非 ASCII 字符,他的回答中的代码在 Python 2 中会中断并出现异常。(Python 2.7.6,Debian):
import json
data = {u'/u0430/u0431/u0432/u0433/u0434': 1} #{u'абвгд': 1}
with open('data.txt', 'w') as outfile:
json.dump(data, outfile)
然而它在 Python 3 中运行良好。
解决方案 7:
使用 JSON 将数据写入文件中,使用json.dump()或json.dumps()。像这样写将数据存储在文件中。
import json
data = [1,2,3,4,5]
with open('no.txt', 'w') as txtfile:
json.dump(data, txtfile)
列表中的这个例子存储到一个文件中。
解决方案 8:
json.dump(data, open('data.txt', 'wb'))
解决方案 9:
所有前面的答案都是正确的,这是一个非常简单的例子:
#! /usr/bin/env python
import json
def write_json():
# create a dictionary
student_data = {"students":[]}
#create a list
data_holder = student_data["students"]
# just a counter
counter = 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 file
file_path='/tmp/student_data.json'
with open(file_path, 'w') as outfile:
print("writing file to: ",file_path)
# HERE IS WHERE THE MAGIC HAPPENS
json.dump(student_data, outfile)
outfile.close()
print("done")
write_json()
解决方案 10:
要使用缩进、“漂亮打印”来编写 JSON:
import json
outfile = open('data.json')
json.dump(data, outfile, indent=4)
此外,如果您需要调试格式不正确的 JSON,并希望获得有用的错误消息,请使用import simplejson
库,而不是import json
(功能应该相同)
解决方案 11:
对于喜欢单行代码的人来说(因此with
语句不是一个选项),比留下悬空的打开的文件描述符更干净的方法是使用write_text
frompathlib
并执行如下操作:
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
(而且它可能会更慢),只是另一种选择。
解决方案 12:
如果你尝试使用 json 格式将 pandas dataframe 写入文件,我推荐这个
destination='filepath'
saveFile = open(destination, 'w')
saveFile.write(df.to_json())
saveFile.close()
解决方案 13:
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)
解决方案 14:
接受的答案很好。但是,我在使用它时遇到了“不是 json 可序列化”错误。
以下是我使用open("file-name.json", 'w')
输出修复它的方法:
output.write(str(response))
虽然这不是一个好的修复方法,因为它创建的 json 文件没有双引号,但如果您正在寻找快速而肮脏的方法,它就很棒。
解决方案 15:
在将字典作为 json 写入文件之前,您必须使用json
库将该字典转换为 json 字符串。
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)
解决方案 16:
如果您喜欢美化(缩进)并使用可选utf-8
编码对 json 进行排序:
import json
js2 = json.dumps(j1, indent=4, sort_keys=True)
fp2 = open('16_02_json_2.json', 'w', encoding='utf-8')
fp2.write(js2)
就是这样!
如果您正在处理写入的文件,请确保刷新或关闭,以便将所有数据缓存写入磁盘:
fp2.flush() # you may still keep working on the file after this
fp2.close() # guaranteed data written to the disk
下面是 JSON 加载的示例,如果您尚未将 JSON 加载为字典。
j1 = json.loads("""
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}
""")
相关:如何漂亮地打印 JSON 文件?
解决方案 17:
这只是对用法的一个额外提示json.dumps
(这不是问题的答案,而是对于那些必须转储 numpy 数据类型的人来说的一个技巧):
如果字典中有 NumPy 数据类型,则json.dumps()
需要额外的参数,归功于TypeError: Object of type 'ndarray' is not JSON serializable,它还将修复类似TypeError: Object of type int64 is not JSON serializable
等错误:
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)))
如果是 np.array(),您可能还想返回字符串而不是列表,因为数组被打印为分布在行上的列表,如果您有大型或许多数组,这将使输出变得庞大。需要注意的是:以后从转储字典中访问项目以将它们作为原始数组返回会更加困难。但是,如果您不介意只有一个数组的字符串,这会使字典更具可读性。然后交换:
elif isinstance(obj, (np.ndarray,)):
return obj.tolist()
和:
elif isinstance(obj, (np.ndarray,)):
return str(obj)
或者只是:
else:
return str(obj)
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件