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

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

这会导致错误:

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


当前回答

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

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

为了说明这一点,接下来是phihag的回答:如果数据包含非ASCII字符,他的回答中的代码在Python 2中中断,出现异常TypeError:必须是unicode,而不是str。(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中运行良好。

其他回答

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

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

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

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

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

为了说明这一点,接下来是phihag的回答:如果数据包含非ASCII字符,他的回答中的代码在Python 2中中断,出现异常TypeError:必须是unicode,而不是str。(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中运行良好。

对于那些试图转储希腊语或其他“外来”语言(如我),但同时也遇到诸如和平符号(\u262E)等奇怪字符或其他通常包含在json格式数据(如Twitter)中的字符的问题(unicode错误)的人,解决方案可能如下(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))

对于喜欢oneliner的人(因此,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]]

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