如何将 JSON 数据写入文件?

2024-11-27 10:42:00
admin
原创
13
摘要:问题描述:如何将字典中存储的 JSON 数据写入data文件?f = open('data.json', 'wb') f.write(data) 这会出现错误:TypeError:必须是字符串或缓冲区,而不是字典解决方案 1:data是一个Python字典,写入前需要编码为JSON。使用这个来获得最大的兼容性...

问题描述:

如何将字典中存储的 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_keysTrueindent4 个空格字符,您就可以开始了。还要注意确保 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_textfrompathlib并执行如下操作:

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)
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   657  
  如何借鉴华为IPD体系优化企业研发?在当今竞争激烈的市场环境中,企业要想保持技术领先和产品竞争力,必须拥有一套高效且严谨的研发管理体系。华为作为全球领先的ICT解决方案提供商,其集成产品开发(IPD, Integrated Product Development)体系与质量管理体系(如ISO 9000系列)的融合实践,...
IPD项目管理   15  
  IPD流程图的7种经典绘制方法详解在产品开发领域,集成产品开发(Integrated Product Development,简称IPD)流程被广泛应用,以提高产品开发的效率和质量。IPD流程图作为这一流程的可视化工具,其绘制方法至关重要。本文将详细介绍七种经典的IPD流程图绘制方法,帮助项目管理人员和团队更好地理解和...
IPD研发管理体系   18  
  IPD流程:企业创新管理的核心引擎在当今快速变化的市场环境中,企业要想持续保持竞争力,就必须不断进行创新。而IPD(Integrated Product Development,集成产品开发)流程作为一种先进的产品开发管理模式,正逐渐成为众多企业提升创新能力、加速产品上市速度、降低开发成本的重要选择。本文将深入探讨IP...
IPD管理   18  
  IPD流程与传统产品开发流程的概述在产品开发领域,企业不断寻求高效、系统的管理方法以确保产品能够顺利从概念转化为市场成功的产品。集成产品开发(Integrated Product Development,简称IPD)流程与传统产品开发流程是两种截然不同的管理理念和方法。传统产品开发流程往往以职能部门为核心,各部门按顺序...
IPD流程中PDCP是什么意思   16  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用