如何将JSON数据写入文件?
我有JSON数据存储在variablesdata
。
我想写这个文本文件进行testing,所以我不必每次都从服务器获取数据。
目前,我正在尝试这个:
obj = open('data.txt', 'wb') obj.write(data) obj.close
我正在收到错误:
TypeError: must be string or buffer, not dict
如何解决这个问题?
你忘了实际的JSON部分 – data
是一个字典,而不是JSON编码。 这样写:
import json with open('data.txt', 'w') as outfile: json.dump(data, outfile)
注意:可以在3.x和2.x上运行。
要获得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'
参数仍然是必需的。
为避免在内存中存储数据的编码副本( dumps
结果)并在Python 2和Python 3中输出utf8编码的字节串,请使用:
import json, codecs with open('data.txt', 'wb') as f: json.dump(data, codecs.getwriter('utf-8')(f), ensure_ascii=False)
在Python 3中, codecs.getwriter
调用是多余的,但对于Python 2是必需的
可读性和大小:
ensure_acsii=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
(由dinos66build议)添加到dump
或dumps
参数,进一步提高可读性。 这样,你将在json文件中得到一个很好的缩进sorting结构,代价是稍大的文件大小。
我会回答上述答案略有修改,那就是写一个美化JSON文件,人眼可以更好地阅读。 为此,将sort_keys
传递为True
并用4个空格字符indent
,然后您就可以走了。 还要注意确保ascii代码不会写入您的JSON文件中:
with open('data.txt', 'w') as outfile: json.dump(jsonData, outfile, sort_keys = True, indent = 4, ensure_ascii = False)
用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
:sorting字典的键。 如果你想比较JSON文件和diff工具/把它们放在版本控制下,这是非常有用的。 -
separators
:防止Python添加尾随空格
创buildJSON文件
{ "a list":[ 1, 42, 3.141, 1337, "help", "€" ], "a string":"bla", "another dict":{ "foo":"bar", "key":"value", "the answer":42 } }
通用文件结尾
.json
备择scheme
- CSV:超简单格式( 读写 )
- JSON:写出人类可读的数据很好, 非常常用( 读写 )
- YAML:YAML是JSON的超集,但更容易阅读( 读写 , 比较JSON和YAML )
- pickle:Python序列化格式( 读写 )
- MessagePack ( Python包 ):更紧凑的表示( 读写 )
- HDF5 ( Python包 ):很好的matrix( 读写 )
- XML:也存在*叹*( 读写 )
对于您的应用程序,以下可能是重要的:
- 支持其他编程语言
- 阅读/写作performance
- 紧凑(文件大小)
另请参阅: 数据序列化格式的比较
如果你正在寻找一种configuration文件的方式,你可能想阅读我的简短文章Pythonconfiguration文件
对于那些试图转储希腊语或其他“异国情调”的语言,如我,但也有问题(统一码错误)与奇怪的人物,如和平符号(\ u262E)或其他经常包含在json格式的数据如Twitter的,解决scheme可能如下(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))
我没有足够的声望来添加评论,所以我只是在这里写下一些令人讨厌的TypeError的发现:
基本上,我认为这是Python 2中的json.dump()
函数中的一个错误 – 它不能转储包含非ASCII字符的Python(字典/列表)数据, 即使您使用encoding = 'utf-8'
参数。 (即不pipe你做什么)。 但是, json.dumps()
适用于Python 2和Python 3。
为了说明这一点,遵循phihag的回答:他的回答中的代码在Python 2中中断, TypeError: must be unicode, not str
如果data
包含非ASCII字符,则TypeError: must be unicode, not 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使用json.dump()或json.dumps()写入数据。 像这样写入将数据存储在文件中。
import json data = [1,2,3,4,5] with open('no.txt', 'w') as txtfile: json.dump(data, txtfile)
列表中的这个例子是存储到一个文件中的。
json.dump(data, open('data.txt', 'wb'))
如果你正在尝试使用json格式将一个pandas数据框写入一个文件,我会推荐这个
destination='filepath' saveFile = open(destination, 'w') saveFile.write(df.to_json()) saveFile.close()
这里是一个有用的结构,在Python 3中读取和写入文件。
from json import dump, load from time import sleep from random import random def json_file(path, data = None, delay = 0.1): while True: try: if data == None: with open(path, "r", encoding = "utf-8") as f: return load(f) else: with open(path, "w", encoding = "utf-8") as f: return dump(data, f) except: sleep(random()*delay) # concurrency