如何向 json 文件追加数据?

我正在尝试创建一个函数,该函数将向 json 文件添加条目。最后,我想要一个文件,看起来像

[{"name" = "name1", "url" = "url1"}, {"name" = "name2", "url" = "url2"}]

等等,这就是我所拥有的:

def add(args):
with open(DATA_FILENAME, mode='r', encoding='utf-8') as feedsjson:
feeds = json.load(feedsjson)
with open(DATA_FILENAME, mode='w', encoding='utf-8') as feedsjson:
entry = {}
entry['name'] = args.name
entry['url'] = args.url
json.dump(entry, feedsjson)

这确实创建了一个条目,比如 {"name"="some name", "url"="some url"}。但是,如果我再次使用这个 add函数,使用不同的名称和 url,第一个函数将被覆盖。我需要做什么来获得第二个(第三个...)条目附加到第一个?

编辑 : 对这个问题的第一个回答和评论指出了一个明显的事实,那就是我没有在写块中使用 feeds。但我不知道该怎么做。例如,下面这些显然是不行的:

with open(DATA_FILENAME, mode='a+', encoding='utf-8') as feedsjson:
feeds = json.load(feedsjson)
entry = {}
entry['name'] = args.name
entry['url'] = args.url
json.dump(entry, feeds)
271241 次浏览

您永远不会写任何与您读入的数据有关的内容。您想要将提要中的数据结构添加到您正在创建的新提要中吗?

或者,您可能希望在追加模式 open(filename, 'a')中打开文件,然后通过编写由 json.dumps而不是使用 json.dump生成的字符串来添加字符串——但是 nnewneo 指出,这将是无效的 json。

使用 a而不是 w应该可以让您更新文件,而不是创建一个新的/覆盖现有文件中的所有内容。

有关模式的差异,请参阅 这个答案

您可能希望使用 JSON 名单而不是 dictionary 作为顶级元素。

因此,用一个空列表初始化该文件:

with open(DATA_FILENAME, mode='w', encoding='utf-8') as f:
json.dump([], f)

然后,您可以将 附录新条目添加到这个列表中:

with open(DATA_FILENAME, mode='w', encoding='utf-8') as feedsjson:
entry = {'name': args.name, 'url': args.url}
feeds.append(entry)
json.dump(feeds, feedsjson)

请注意,这将执行得很慢,因为每次调用 add时都会重写文件的完整内容。如果您在循环中调用它,可以考虑提前将所有提要添加到列表中,然后一次性将列表写出来。

Json 可能不是磁盘格式的最佳选择; 附加数据的麻烦就是一个很好的例子。具体来说,json 对象的语法意味着必须读取和解析整个对象,以便理解其中的任何部分。

幸运的是,还有很多其他选择。一个特别简单的是 CSV; python 的标准库很好地支持它。最大的缺点是,它只适用于文本; 如果需要,它需要程序员执行额外的操作来将值转换为数字或其他格式。

另一个没有这个限制的选项是使用 sqlite 数据库,它在 python 中也有内置支持。这可能与您已有的代码有更大的不同,但是它更自然地支持您显然正在尝试构建的“稍微修改一下”模型。

如果文件存在,则将条目追加到文件内容,否则将条目追加到空列表并在文件中写入:

a = []
if not os.path.isfile(fname):
a.append(entry)
with open(fname, mode='w') as f:
f.write(json.dumps(a, indent=2))
else:
with open(fname) as feedsjson:
feeds = json.load(feedsjson)


feeds.append(entry)
with open(fname, mode='w') as f:
f.write(json.dumps(feeds, indent=2))

一个可能的解决方案是手动进行连接,这里有一些有用的方法 密码:

import json
def append_to_json(_dict,path):
with open(path, 'ab+') as f:
f.seek(0,2)                                #Go to the end of file
if f.tell() == 0 :                         #Check if file is empty
f.write(json.dumps([_dict]).encode())  #If empty, write an array
else :
f.seek(-1,2)
f.truncate()                           #Remove the last character, open the array
f.write(' , '.encode())                #Write the separator
f.write(json.dumps(_dict).encode())    #Dump the dictionary
f.write(']'.encode())                  #Close the array

在编辑脚本之外的文件时应该小心,不要在末尾添加任何间距。

我有一些代码是类似的,但不重写整个内容的每一次。这意味着要定期运行并在数组的末尾附加一个 JSON 条目。

如果该文件尚不存在,它将创建该文件并将 JSON 转储到一个数组中。如果已经创建了文件,那么它将进入末尾,用 ,替换 ],放入新的 JSON 对象,然后再用另一个 ]关闭它

# Append JSON object to output file JSON array
fname = "somefile.txt"
if os.path.isfile(fname):
# File exists
with open(fname, 'a+') as outfile:
outfile.seek(-1, os.SEEK_END)
outfile.truncate()
outfile.write(',')
json.dump(data_dict, outfile)
outfile.write(']')
else:
# Create file
with open(fname, 'w') as outfile:
array = []
array.append(data_dict)
json.dump(array, outfile)

这个,为我工作:

with open('file.json', 'a') as outfile:
outfile.write(json.dumps(data))
outfile.write(",")
outfile.close()

您可以简单地从源文件中导入数据,读取它,并保存要附加到变量的内容。然后打开目标文件,将内部的列表数据分配给一个新变量(假设这些都是有效的 JSON) ,然后对这个列表变量使用‘ append’函数,并将第一个变量附加到它。Viola,您已经附加到了 JSON 列表。现在只需用新添加的列表(如 JSON)覆盖目标文件即可。

您的‘ open’函数中的‘ a’模式在这里不起作用,因为它只会将所有内容粘贴到文件的末尾,这将使其成为无效的 JSON 格式。

import jsonlines


object1 = {
"name": "name1",
"url": "url1"
}


object2 = {
"name": "name2",
"url": "url2"
}




# filename.jsonl is the name of the file
with jsonlines.open("filename.jsonl", "a") as writer:   # for writing
writer.write(object1)
writer.write(object2)


with jsonlines.open('filename.jsonl') as reader:      # for reading
for obj in reader:
print(obj)

更多信息请访问 https://jsonlines.readthedocs.io/en/latest/

我们假设你有以下的表达方式

d1 = {'a': 'apple'}
d2 = {'b': 'banana'}
d3 = {'c': 'carrot'}

你可以把它变成这样的 json 组合:

master_json = str(json.dumps(d1))[:-1]+', '+str(json.dumps(d2))[1:-1]+', '+str(json.dumps(d3))[1:]

因此,添加到 json 文件的代码如下所示:

        dict_list = [d1, d2, d3]
for i, d in enumerate(d_list):
if i == 0:
#first dict
start = str(json.dumps(d))[:-1]
with open(str_file_name, mode='w') as f:
f.write(start)
else:
with open(str_file_name, mode='a') as f:
if i != (len(dict_list) - 1):
#middle dicts
mid = ','+str(json.dumps(d))[1:-1]
f.write(mid)
else:
#last dict
end = ','+str(json.dumps(d))[1:]
f.write(end)