如何将JSON数据写入文件?

How do I write JSON data to a file?

提问人:user1530318 提问时间:9/7/2012 最后编辑:Mateen Ulhaquser1530318 更新时间:11/25/2022 访问量:2581553

问:

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

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

这给出了错误:

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

蟒蛇 JSON

评论

0赞 Charlie Parker 9/23/2020
对于打开文件时的标志:在这里,我们在参数中使用了“w”字母,表示写入,如果库中不存在文件,它将创建一个文件 加号表示读取和写入,guru99.com/reading-and-writing-files-in-python.html#1
2赞 johnthagen 7/21/2022
pathlib 与一行一起使用:Path("data.json").write_text(json.dumps(data))

答:

3087赞 phihag 9/7/2012 #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 文档。

评论

252赞 phihag 8/14/2015
@TerminalDilettante写入文件或类似文件的对象,而返回一个字符串。json.dumpjson.dumps
0赞 curiouscheese 7/30/2023
JSON dump 会将 JSON 作为字符串写入文件中。我怎样才能得到一个不是字符串形式的json文件,而只是字典式的?可能吗?
1赞 phihag 7/31/2023
@curiouscheese 听起来像是在 StackOverflow 上问的好问题!当你说字典时,一定要解释你的意思——也许你可以给出一个示例文件?归根结底,文件只是一系列字节。
0赞 curiouscheese 7/31/2023
我已经找到了解决方案。我想在json文件中的样子是,而不是.我只是将上下文管理器与 一起使用,而不是 并且它可以工作。因为我生成的 json 字符串来自 .[{"name":"Jack", "age":34}, {"name":"Joe", "age":54}]"[{"name":"Jack", "age":34}, , {"name":"Joe", "age":54}]"f.write(json_string)json.dumps(json_string)dataframe.to_json()
328赞 Antony Hatchkins 2/14/2013 #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 上,参数 to 仍然是必要的。encoding='utf-8'open

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

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

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

评论

5赞 phihag 2/14/2013
是多余的 - 的结果已经是一个 unicode 对象。请注意,这在 3.x 中失败了,其中输出文件模式的整个混乱已被清理干净,并且 json 始终使用字符串(和字符 I/O)而不是字节。unicodejson.dumps
193赞 ambodi 12/26/2013 #3

我会对上述答案稍作修改,即编写一个人眼可以更好地阅读的美化 JSON 文件。为此,使用 4 个空格字符传递 as,您就可以开始了。还要注意确保 ascii 代码不会写入 JSON 文件中:sort_keysTrueindent

with open('data.txt', 'w') as out_file:
     json.dump(json_data, out_file, sort_keys = True, indent = 4,
               ensure_ascii = False)
26赞 dinos66 7/10/2015 #4

对于那些试图抛弃希腊语或其他“异国情调”语言的人,比如我,但也遇到了奇怪的字符(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))
11赞 Vishal Gediya 12/24/2015 #5

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

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

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

评论

0赞 Vishal Gediya 2/17/2017
它很相似,但提供了示例
13赞 ibic 1/3/2016 #6

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

基本上,我认为这只是 Python 2 中函数中的一个错误 - 它无法转储包含非 ASCII 字符的 Python(字典/列表)数据,即使您使用参数打开文件也是如此。(即无论你做什么)。但是,适用于 Python 2 和 3。json.dump()encoding = 'utf-8'json.dumps()

为了说明这一点,跟进 phihag 的回答:如果包含非 ASCII 字符,则他的答案中的代码在 Python 2 中会中断,但有例外。(Python 2.7.6,Debian):TypeError: must be unicode, not strdata

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 中工作正常。

评论

0赞 ibic 2/13/2017
@AntonyHatchkins 你是对的。我刚刚意识到 Python 2 中的包需要,而不是。unicode()iowrite()unicodestr
1赞 Antony Hatchkins 2/21/2017
即使使用 python2.6.6,Debian(2010 年 12 月 10 日),此代码也适用于我。以及 python2.7.9 或 python3。请再检查一次。
7赞 Alexander 3/1/2016 #7
json.dump(data, open('data.txt', 'wb'))

评论

3赞 Antony Hatchkins 2/10/2017
这与@phihag的答案相同,但不能保证在任何时候都有效。请考虑以下代码:.运行它,然后运行SYGTERM(然后在Linux上,在Windows上)。 将有 0 个字节。这是因为在发生 SYGTERM 的那一刻,写入是缓冲的,并且文件既没有被刷新,也没有关闭。 块保证文件始终像“try/finally”块一样关闭,但更短。f = open('1.txt', 'w'); f.write('a'); input()Ctrl-Zkill %1Ctrl-Break1.txtwith
1赞 kriss 11/25/2022
如果你喜欢 oneliners,一个更简洁的选择可能是使用 pathlib 并执行类似 'pathlib.路径(“data.txt”).write_text(json.dumps(data))'
131赞 Martin Thoma 6/14/2016 #8

使用 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:对字典的键进行排序。如果您想将 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

选择

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

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

另请参阅:数据序列化格式的比较

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

3赞 Franco Miguel Contreras 6/3/2017 #9

如果您尝试使用 JSON 格式将 Pandas DataFrame 写入文件,我建议您这样做

destination='filepath'
saveFile = open(destination, 'w')
saveFile.write(df.to_json())
saveFile.close()
5赞 grepit 10/10/2018 #10

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

#! /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()

enter image description here

3赞 Akshat Bajaj 10/15/2018 #11

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

这是我修复它的方法 替换为输出:open("file-name.json", 'w')

output.write(str(response))

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

3赞 Ashok Kumar Jayaraman 11/1/2018 #12

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)
6赞 James Wierzba 12/14/2018 #13

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

import json

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

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

评论

0赞 Mihai Todor 4/26/2021
不以只读模式打开文件?open('data.json')
0赞 questionto42 9/13/2021 #14

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

如果字典中有 NumPy 数据类型,需要额外的参数,则将转到 TypeError:类型为“ndarray”的对象不可 JSON 序列化,它还将修复错误,例如:json.dumps()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)

评论

0赞 user32882 11/2/2021
多么迂回的方式来做一些非常简单的事情
1赞 questionto42 11/2/2021
@user32882 是的,这也让我感到惊讶。像 json.dumps 这样的标准的弱点。它被否决可能是因为没有人期望它如此复杂(包括我),而且它并没有真正回答这个问题,但就我而言,我需要它。
0赞 user32882 11/2/2021
请看一下接受的答案。这应该不会超过几行代码。
0赞 questionto42 11/2/2021
@user32882 据我所知,接受的答案无法导出 numpy 数据类型,这就是我添加此答案的原因。不过,我不确定 和 之间关于 numpy 数据类型是否存在差异,我现在不能花时间测试它,我想我无论如何都测试了这个。这个答案不会取代被接受的答案,而是添加这个特殊情况(一点也不特殊,numpy 数据类型很常见)。json.dumpjson.dumps
0赞 questionto42 11/3/2021
@user32882 阅读您的评论,您还没有理解这个答案。这里或多或少重复了接受的答案(而不是这里,以便您可以使用参数),并且只是添加了使 numpy 导出成为可能的类。不反对为了正确的缘故投反对票,但请仔细考虑一下。dumpsdump
4赞 Kavindu Ravishka 6/16/2022 #15

在将字典作为 json 写入文件之前,您必须使用 library 将该字典转换为 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)
4赞 kriss 11/25/2022 #16

对于喜欢单行代码的人来说(因此语句不是一种选择),比留下悬空的打开文件描述符更干净的方法可能是使用并执行如下操作:withwrite_textpathlib

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