我正在从API下载Json文件,我使用以下代码编写JSON。循环中的每个项目都给我一个JSON文件。我需要保存它并使用循环从附加的JSON文件中提取实体。
for item in style_ls:
dat = get_json(api, item)
specs_dict[item] = dat
with open("specs_append.txt", "a") as myfile:
json.dump(dat, myfile)
myfile.close()
print item
with open ("specs_data.txt", "w") as my file:
json.dump(spec_dict, myfile)
myfile.close()
我知道我无法从specs_append.txt
获取有效的JSON格式,但我可以从specs_data.txt
获得一个。我正在做第一个,因为我的程序需要至少3-4天才能完成,并且我的系统很可能会关闭。那么无论如何我能有效地做到这一点吗?
如果没有,我可以从specs_append.txt
<{JSON}{JSON}>
格式(这不是有效的JSON格式)中提取它吗?
如果不是,我应该每次在循环中将specs_dict写入txt文件,这样即使程序被终止,我也可以从循环中的那个点开始并仍然获得有效的json格式?
答案 0 :(得分:2)
在每个循环中将json
数据附加到dict
。
最后将此dict
转储为json
并将其写入文件。
为了让您了解将数据附加到dict:
>>> d1 = {'suku':12}
>>> t1 = {'suku1':212}
>>> d1.update(t1)
>>> d1
{'suku1': 212, 'suku': 12}
答案 1 :(得分:1)
我建议几种可能的解决方案。
一种解决方案是将自定义代码写入输入文件中的slurp。我建议在文件中的每个JSON对象之前放一个特殊行,例如:###
然后你可以写这样的代码:
import json
def json_get_objects(f):
temp = ''
line = next(f) # pull first line
assert line == SPECIAL_LINE
for line in f:
if line != SPECIAL_LINE:
temp += line
else:
# found special marker, temp now contains a complete JSON object
j = json.loads(temp)
yield j
temp = ''
# after loop done, yield up last JSON object
if temp:
j = json.loads(temp)
yield j
with open("specs_data.txt", "r") as f:
for j in json_get_objects(f):
pass # do something with JSON object j
关于此的两点说明。首先,我只是一遍又一遍地追加一个字符串;这曾经是在Python中执行此操作的一种非常慢的方式,因此如果您使用的是非常旧版本的Python,除非您的JSON对象非常小,否则不要这样做。其次,我编写了一个代码来分割输入并一次一个地生成JSON对象,但是你也可以使用一个保证唯一的字符串,只需一次调用f.read()
就可以在所有数据中啜饮,然后拆分你的使用str.split()
方法函数保证唯一字符串。
另一种解决方案是将整个文件写为有效JSON对象的有效JSON列表。像这样写文件:
{"mylist":[
# first JSON object, followed by a comma
# second JSON object, followed by a comma
# third JSON object
]}
这将要求您的文件附加代码以使用写入权限打开文件,并在编写逗号和换行符之前搜索文件中的最后]
,然后在最后找到新的JSON对象,最后写]}
来关闭文件。如果你这样做,你可以使用json.loads()
来填充整个内容,并有一个JSON对象列表。
最后,我建议您可以只使用数据库。使用SQLite或其他东西,只需将JSON字符串放入表中即可。如果你选择这个,我建议使用ORM来简化你的生活,而不是手工编写SQL命令。
就个人而言,我赞成第一个建议:写一个像###
这样的特殊行,然后使用自定义代码拆分那些标记上的输入,然后获取JSON对象。
{
"foo": 0,
"bar": 1,
"baz": 2
}
但它们都是一条长长的路线:
{"foo":0,"bar":1,"baz":2}
以下是解决此问题的三种方法。
0)在###
之前和之后写一个换行符,如下所示:
###
{"foo":0,"bar":1,"baz":2}
###
{"foo":0,"bar":1,"baz":2}
然后每个输入行将交替为###
或完整的JSON对象。
1)只要SPECIAL_LINE
完全唯一(永远不会出现在JSON中的字符串中),您就可以这样做:
with open("specs_data.txt", "r") as f:
temp = f.read() # read entire file contents
lst = temp.split(SPECIAL_LINE)
json_objects = [json.loads(x) for x in lst]
for j in json_objects:
pass # do something with JSON object j
.split()
方法函数可以将temp
字符串拆分为JSON对象。
2)如果您确定每个JSON对象都不会在其中包含换行符,您可以简单地将JSON对象一个接一个地写入该文件,然后在每个对象之后放置换行符;然后假设每一行都是一个JSON对象:
import json
def json_get_objects(f):
for line in f:
if line.strip():
yield json.loads(line)
with open("specs_data.txt", "r") as f:
for j in json_get_objects(f):
pass # do something with JSON object j
我喜欢选项(2)的简单性,但我喜欢选项(0)的可靠性。如果换行符作为JSON对象的一部分写入,则选项(0)仍然有效,但选项(2)会出错。
同样,您也可以简单地将实际数据库(SQLite)与ORM一起使用,让数据库担心细节。
祝你好运。