我将JSON数据存储在变量data中。
我想把它写到一个文本文件中进行测试,这样我就不必每次都从服务器中获取数据。
目前,我正在尝试:
1 2 3
| obj = open('data.txt', 'wb')
obj.write(data)
obj.close |
我收到错误:
TypeError: must be string or buffer, not dict
如何解决这个问题?
你忘了JSON是一部分目前尚未data词典和JSON编码的。是这样写的:
1 2 3
| import json
with open('data.json', 'w') as outfile:
json.dump(data, outfile) |
注:作品在3.x和2.0。
- 这可能有助于序列化:stackoverflow.com/questions/4512982/…
- 您是指json.dump还是json.dumps?
- @terminaldilettante json.dump写入文件或类似文件的对象,而json.dumps返回字符串。
- btw:要重新读取数据,请使用open("data.txt")作为infile:d=json.load(infile)。看:这个答案
- 这应该是"wb"而不是"w"(速度等)吗?
- @丹瓦尔不,这个答案是经过精心调整的。在python 3上,json.dump写入文本文件,而不是二进制文件。如果文件是用wb打开的,您将得到一个TypeError。在旧的python版本中,w和wb都可以工作。不需要显式编码,因为默认情况下json.dump的输出是ASCII。如果您可以确保您的代码永远不会在旧的Python版本上运行,并且您和JSON文件的处理程序能够正确处理非ASCII数据,那么您可以指定一个并设置ensure_ascii=False。
- @你能详细说明你为什么这么想吗?这个问题涉及到如何写入名为data.txt的文件。在任何情况下,文件名都不重要。
- 是的,它有效。但该解决方案为python2和python3提供7bit输出:所有非ASCII字符都编码为ASCII(例如,'π'编码为6字节:'\u03c0'。现在最好有UTF8编码的JSON文件。它们比XML小3倍('π'编码为两个字节:b'\xcf\x80'加上它们在任何现代编辑器中都是可读的(与XML相比,可读性是json的主要优势之一)。详情请参阅下面的答案。
- 我在python 3中碰到了"File"/Users/gg4u/Sites/expo_recipes_2015/scraper.py", line 282, in downloadRecipe json.dump({'data' : 'data'}, out_file) File"/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 180, in dump fp.write(chunk) TypeError: a bytes-like object is required, not 'str' "。
- 结果文件"data.txt"保存在哪里?如何在Ubuntu 16.04上访问它?
- @Krazzyr代替了data.txt,您可以在任何路径上传递您想要的文件。例如,如果你的用户名是Ubuntu上的krazzyr,你可以输入'/home/krazzyr/Desktop/myfile.json',文件就会出现在你的桌面上。如果路径不是以斜杠(/开头),则它是相对于当前工作目录的。例如,如果您的工作目录是/home/krazzyr,您输入data.txt,文件名将是/home/krazzyr/data.txt。在shell中,可以键入pwd来打印工作目录。
- @你如何进入它取决于你想做什么。流行的选项包括命令行文本编辑器(如nano或vi)、图形文本编辑器(如emacs、kwrite、gedit或sublime文本)、IDES编辑器(如vscode和eclipse)、命令行输出(带cat或less以及带jq的彩色或过滤显示。通常,在命令行中,键入要运行的程序,然后键入路径。同样,路径可以是相对的或绝对的。例如,如果您将文件保存到/home/krazzyr/Desktop/myfile.json,并且您的工作目录是/home/krazzyr,那么gedit Desktop/myfile.json就可以了。
- 感谢您提供如此有用和详细的解释。(我主要是一个迁移到python的r用户。)因此,将open('data.txt', 'w')更改为open('/home/krazzyr/data.txt', 'w') 将创建一个文件'data.txt',并将该文件保存到home/krazzyr/中。
- @Krazzyr几乎:绝对路径以斜线开头,因此文件将以/home/krazzyr结尾-注意前面的斜线。但是不要害怕相对路径,它们通常更有用。如果您只指定data.txt并在/home/krazzyr中运行程序(默认),那么您的文件也将以/home/krazzyr/结尾。但当我在/home/phihag/stackoverflow/中运行您的程序时,它会将它写入/home/phihag/stackoverflow/。这很有用,因为我的系统中可能不存在/home/krazzyr/,而且无论如何,我希望程序的输出位于子目录中。
- 在我的程序中,我有一个运行三次的方法。所以我把a换成了w。现在,如何在每次运行后向输出文件添加新行或类似的内容,以便区分由此生成的文件中的所有三个不同输出:import json with open('data.txt', 'a') as outfile: json.dump(data, outfile)。
- @这听起来是个很好的问题。继续在stackoverflow上询问!
- @如果你问这个问题,请在这里发表评论链接。我想这关系已经够大了。
- 是的。但当我找到一个解决方案时,我的问题被标记为重复。这里是:stackoverflow.com/questions/47140526/…
- 为了完整性,您如何读取您编写的文件?
- @古尔扎,这是另一个问题。(扰流器:使用json.load)
为了得到UTF8编码的ASCII编码的文件到喷嘴对置在接受答案2:在Python中使用
1 2 3
| import io, json
with io.open('data.txt', 'w', encoding='utf-8') as f:
f.write(json.dumps(data, ensure_ascii=False)) |
该代码是基于Python的simpler 3:
1 2 3
| import json
with open('data.txt', 'w') as f:
json.dump(data, f, ensure_ascii=False) |
在Windows的问题,encoding='utf-8'到open仍然是必要的。
一种避免复制的数据储存在记忆编码(result of dumps)和两个输出bytestrings UTF8编码,Python中的2和3,使用方法:
1 2 3
| import json, codecs
with open('data.txt', 'wb') as f:
json.dump(data, codecs.getwriter('utf-8')(f), ensure_ascii=False) |
在Python中的呼叫是一codecs.getwriterredundant 2 3,但需要在Python
readability和大小:
使用了更好的ensure_ascii=Falsereadability和较小的尺寸:
1 2 3 4 5 6 7 8 9
| >>> 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 |
进一步提高通过添加readability(旗)的建议indent=4, sort_keys=Truedinos66)或受dumpdumps)。你会得到这样的nicely indented JSON文件中的类结构,在成本点较大的文件大小。
- unicode是多余的—json.dumps的结果已经是unicode对象了。注意,这在3.x中失败了,在3.x中,输出文件模式的混乱已经被清除,JSON总是使用字符串(和字符I/O)而不是字节。
- 在2.x中,type(json.dumps('a'))是。即使是type(json.dumps('a', encoding='utf8'))也是。
- 是的,在3.x JSON中使用字符串,但默认编码是ASCII。你必须明确地告诉它你想要utf8,即使是在3.x中。更新了答案。
- 哦,你完全是对的-我一定弄混了什么。+1表示细节。
- 数据提供者(如Twitter)有时提供各种编码的数据。上面的代码对所有Unicode tweet都适用,但在某些情况下,拉丁符号会出现,并且会出现如下错误:"unicodeencodeerror:'charmap'codec can't encode character''xdc'in position 3088:character maps to",您对这些情况下可以做什么有什么想法?
- @DINOS66是否可以将字符串打印到Unicode控制台而不出现此错误?尝试本地化问题,在有问题的符号前后找到至少5-7个字节,并在这里引用它们。我的版本是字符串之前被错误地解码为Unicode。
- @安东尼哈金斯感谢你的关注。我用编解码器库解决了这个问题。所以我的解决方案是:使用codecs.open("data.txt"、"w"、"utf8")作为outfile:outfile.write(json.dumps(json data,sort_keys=true,ensure_ascii=false))。
- 虽然我使用的是2.7,但python 3.x的答案还是对我有效。2.x回答返回一个错误:'ascii' codec can't decode byte 0xf1 in position 506755: ordinal not in range(128)。因此,如果有疑问,请使用3.x答案!
- @blairg23这是因为您在处理单字节编码中的非ascii str。这是强烈反对的。文字使用u''符号,而不是''符号。例如,unicode('абвгд')在python2.x中给出了一个错误:您必须显式地将字符串'абвгд'.decode('utf8')或使用u'абвгд'符号。
- 对我来说,在python3中,codecs.getwriter是必需的。否则:json.dump( recipe , ensure_ascii=False) TypeError: dump() missing 1 required positional argument: 'fp'。
- @用户305883这是因为您遗漏了一个必需的位置参数fp。不需要getwriter,但需要f。请参阅我的python3.x解决方案
- @cas感谢您的编辑,我已经修正了一些拼写错误,但总体来说,这样写会带来更好的阅读体验:)
- 当上面的方法在我的文件中插入控制源''和反斜杠''时,这对我很有用。
- 这是一个比公认的更好的答案,因为它传达了这里所有事情的复杂性。也就是说,我仍然不完全理解为什么使用编码显式上下文管理器with io.open('data.txt', 'w', encoding='utf-8') as f:的解决方案不能用于json.dump方法,但这帮助我解决了codex.getwriter('utf-8')(f)和二进制访问的问题。我猜这与json.dump的预期有关,但在阅读时,我不知道到底在做什么。
- 对于python 3.6.1,我必须添加关键字参数encoding='utf-8'才能打开,以便获得正确的utf-8文件编码:import json with open('data.txt', 'w') as f: json.dump(data, f, ensure_ascii=False)。
- @里克,你的操作系统是什么?
- @安东尼哈金斯赢得10×64。
- @里克,是的,谢谢,我已经更新了答案。
我要的答案与答案和轻微的修改与aforementioned就是写一个prettified JSON文件可以读更好的人的眼睛。这是通的,sort_keysTrue和indent4空间与人物和你是好去。也照顾的ASCII码将确保不会被写在你的JSON文件。
1 2 3
| with open('data.txt', 'w') as outfile:
json.dump(jsonData, outfile, sort_keys = True, indent = 4,
ensure_ascii = False) |
- 仍在获取EDOCX1[10]
- @sirbenbenji确保要写入的字符串如下:str.decode('utf-8')。
- @Sirbenbenji您也可以尝试使用编解码器,正如下面Dinos66指定的那样。
- 您还必须在shebang之后添加# -*- coding: utf-8 -*-来声明您的编码。
- +1表示排序键和缩进。@aesede添加这一行是没有好处的,因为它会给人留下这样的印象:这个解决方案也可以与python2一起工作,而python2不工作(UnicodeEncodeError使用非ascii数据)。有关详细信息,请参阅我的解决方案。
读与写的Python和JSON文件2+3与Unicode的作品;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| # -*- 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文件与不同的工具在他们控制下的版本号。
- Python的:从预防separatorswhitespaces加尾
与封装
有一个看我的超级简单实用mpu是封装和容易记住的一个:
1 2 3
| import mpu.io
data = mpu.io.read('example.json')
mpu.io.write('example.json', data) |
创建JSON文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| {
"a list":[
1,
42,
3.141,
1337,
"help",
"€"
],
"a string":"bla",
"another dict":{
"foo":"bar",
"key":"value",
"the answer":42
}
} |
普通文件的结局
.json
选择
- 超级简单的格式(CSV):读与写
- JSON是可读的写作:尼斯(很常用的数据;读取及写入)
- YAML是一个JSON:YAML superset),但更容易阅读(阅读及写,比较和YAML格式)
- 泡菜:Python serialization格式(读与写
- messagepack(Python Package):更紧凑的表示(读与写
- (调用Python Package):如果尼斯(读与写的矩阵)
- :*叹气*我为XML(读与写
为您的应用程序,下面的可能是重要的。
- 其他编程语言的支持。
- 阅读和写作的性能
- 紧性(文件大小)
国有企业也比较serialization:日期格式
你的情况,而不是寻找的方式,使配置文件,你可能想读我的配置文件在Python的短文章
- 注意,默认情况下,force_ascii标志是True。在JSON文件(以及任何其他非ASCII字符)中,每个€都有不可读的6字节"\u20ac"序列。
- 你为什么用open读,用io.open写?是否也可以使用io.open进行阅读?如果是,应该传递哪些参数?
- 我会投500次赞成票,做得很好。
为那些你谁是试图转储或其他"异国情调"的希腊语,但我也是有这样的问题发生的奇怪的字符的Unicode)与和平的符号(如u262e)或他人通常是包含在formated JSON数据,如Twitter的,该解决方案可以被排序为(_显然是可选的)。
1 2 3
| import codecs, json
with codecs.open('data.json', 'w', 'utf8') as f:
f.write(json.dumps(data, sort_keys = True, ensure_ascii=False)) |
- +1虽然docs推荐python3内置open和相关io.open而不是codecs.open,但在这种情况下,它也是一个很好的向后兼容的黑客。在python2中,codecs.open比io.open更"杂食"(它可以同时"吃"str和unicode,必要时可以转换)。可以说,这个codecs.openquirk补偿了生成不同类型对象(str/unicode)的json.dumpsquirk,这取决于输入中是否存在unicode字符串。
我有足够的信誉来添加评论,所以我想写一些我的调查结果在本annoying TypeError
基本上,我认为这是错误json.dump()函数在Python中的2 -它可以只转储(T /列表的Python字典含非ASCII字符数据),即使你用开放的encoding = 'utf-8'参数文件。(即在你的物。但在Python中,json.dumps()厂2和3。
这说明指南,随访phihag’s答案:答案:代码在Python中与他的休息TypeError: must be unicode, not str2异常,如果data包含非ASCII字符。(Python 2.7.6,Debian的):
1 2 3 4
| 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。
- 当你声称有什么不对劲时,要给出理由。使用@nickname通知此人。您不能写评论,但可以阅读评论。如我对第一条评论的回答中所述,试试data = {'asdf': 1}。你的(第二个)变种会得到臭名昭著的TypeError。
- 关于ensure_ascii—如果您想要得到一个"真正的"utf8输出,这是必要的。如果没有它,您将拥有纯ASCII,每个俄语字母6个字节,而不是每个带此标志的字符2个字节。
- @安东尼哈金斯,你是适合埃多克斯的。我刚刚意识到在python 2中的io包,write()需要unicode,而不是str。
- 此代码适用于我,即使与Python2.6.6,Debian(2010年12月10日)。也可以使用python2.7.9或python3。请再检查一遍。
使用JSON文件中写入数据,使用json.dump json.dumps()或()的使用。写数据到文件中像这样的商店。
1 2 3 4
| import json
data = [1,2,3,4,5]
with open('no.txt', 'w') as txtfile:
json.dump(data, txtfile) |
在这个例子中是存储到文件中。
- 它与公认的答案有什么不同?
- 这是相似的,但请举例说明
1
| json.dump(data, open('data.txt', 'wb')) |
- 这和@phihag的答案是一样的,但并不能保证在任何时候都有效。考虑这样的代码:f = open('1.txt', 'w'); f.write('a'); input()。运行它,然后运行sygterm it(Linux上的Ctrl-Z,Linux上的kill %1,Windows上的Ctrl-Break)。1.txt将有0个字节。这是因为写入被缓冲,并且文件既没有刷新,也没有在sygterm发生时关闭。with块保证文件总是像"try/finally"块那样关闭,但要短一些。
要使用缩进编写JSON,"漂亮的打印":
1 2 3 4
| import json
outfile = open('data.json')
json.dump(data, outfile, indent=4) |
另外,如果您需要调试格式不正确的JSON,并且需要一条有用的错误消息,请使用import simplejson库,而不是import json库(函数应该相同)。
如果您试图使用JSON格式将PANDAS数据帧写入文件,我建议您这样做
1 2 3 4
| destination='filepath'
saveFile = open(destination, 'w')
saveFile.write(df.to_json())
saveFile.close() |
JSON数据可以如下写入文件
1 2 3 4 5 6 7 8
| 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]}] |
写入文件:
1 2
| with open('text1.json', 'w') as f:
json.dump(hist1, f) |
接受的答案是好的。但是,我使用它遇到了"is not json serializable"错误。
我就是这样修理的以open("file-name.json", 'w')为输出:
output.write(str(response))
虽然它并不是一个很好的修复方法,因为它创建的JSON文件不会有双引号,但是如果您要查找快速而脏的文件,这是非常好的。
前面所有的答案都是正确的,下面是一个非常简单的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #! /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() |