Python读取JSON文件并修改
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21035762/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python read JSON file and modify
提问by codeBarer
Hi I am trying to take the data from a json file and insert and id then perform POST REST. my file data.json has:
嗨,我正在尝试从 json 文件中获取数据并插入和 id,然后执行 POST REST。我的文件 data.json 有:
{
'name':'myname'
}
and I would like to add an id so that the json data looks like:
我想添加一个 id,以便 json 数据如下所示:
{
'id': 134,
'name': 'myname'
}
So I tried:
所以我试过:
import json
f = open("data.json","r")
data = f.read()
jsonObj = json.loads(data)
I can't get to load the json format file. What should I do so that I can convert the json file into json object and add another id value.
我无法加载 json 格式文件。我该怎么做才能将 json 文件转换为 json 对象并添加另一个 id 值。
采纳答案by falsetru
Set item using data['id'] = ....
使用 设置项目data['id'] = ...。
import json
with open('data.json', 'r+') as f:
data = json.load(f)
data['id'] = 134 # <--- add `id` value.
f.seek(0) # <--- should reset file position to the beginning.
json.dump(data, f, indent=4)
f.truncate() # remove remaining part
回答by VadimBelov
falsetru's solution is nice, but has a little bug:
falsetru 的解决方案很好,但有一个小错误:
Suppose original 'id' length was larger than 5 characters. When we then dump with the new 'id' (134 with only 3 characters) the length of the string being written from position 0 in file is shorterthan the original length. Extra chars (such as '}') left in file from the original content.
假设原始 'id' 长度大于 5 个字符。当我们使用新的“id”(134 个只有 3 个字符)转储时,从文件中的位置 0 开始写入的字符串的长度比原始长度短。原始内容在文件中留下的额外字符(例如“}”)。
I solved that by replacing the original file.
我通过替换原始文件解决了这个问题。
import json
import os
filename = 'data.json'
with open(filename, 'r') as f:
data = json.load(f)
data['id'] = 134 # <--- add `id` value.
os.remove(filename)
with open(filename, 'w') as f:
json.dump(data, f, indent=4)
回答by Vadym Pasko
I would like to present a modified version of Vadim's solution. It helps to deal with asynchronous requests to write/modify json file. I know it wasn't a part of the original question but might be helpful for others.
我想介绍 Vadim 解决方案的修改版本。它有助于处理写入/修改 json 文件的异步请求。我知道这不是原始问题的一部分,但可能对其他人有帮助。
In case of asynchronous file modification os.remove(filename)will raise FileNotFoundErrorif requests emerge frequently. To overcome this problem you can create temporary file with modified content and then rename it simultaneously replacing old version. This solution works fine both for synchronous and asynchronous cases.
在异步文件修改的情况下,如果请求频繁出现,os.remove(filename)则会引发FileNotFoundError。为了克服这个问题,您可以创建具有修改内容的临时文件,然后同时重命名替换旧版本。此解决方案适用于同步和异步情况。
import os, json, uuid
filename = 'data.json'
with open(filename, 'r') as f:
data = json.load(f)
data['id'] = 134 # <--- add `id` value.
# add, remove, modify content
# create randomly named temporary file to avoid
# interference with other thread/asynchronous request
tempfile = os.path.join(os.path.dirname(filename), str(uuid.uuid4()))
with open(tempfile, 'w') as f:
json.dump(data, f, indent=4)
# rename temporary file replacing old file
os.rename(tempfile, filename)
回答by aaronlhe
There is really quite a number of ways to do this and all of the above are in one way or another valid approaches... Let me add a straightforward proposition. So assuming your current existing json file looks is this....
确实有很多方法可以做到这一点,以上所有方法都是以一种或另一种有效的方法......让我添加一个简单的命题。因此,假设您当前现有的 json 文件看起来是这样的....
{
"name":"myname"
}
And you want to bring in this new json content (adding key "id")
并且你想引入这个新的json内容(添加键“id”)
{
"id": "134",
"name": "myname"
}
My approach has always been to keep the code extremely readable with easily traceable logic. So first, we read the entire existing json file into memory, assuming you are very well aware of your json's existing key(s).
我的方法一直是通过易于追踪的逻辑来保持代码的可读性。因此,首先,我们将整个现有的 json 文件读入内存,假设您非常了解 json 的现有密钥。
import json
# first, get the absolute path to json file
PATH_TO_JSON = 'data.json' # assuming same directory (but you can work your magic here with os.)
# read existing json to memory. you do this to preserve whatever existing data.
with open(PATH_TO_JSON,'r') as jsonfile:
json_content = json.load(jsonfile) # this is now in memory! you can use it outside 'open'
Next, we use the 'with open()' syntax again, with the 'w' option. 'w' is a write mode which lets us edit and write new information to the file. Here s the catch that works for us ::: any existing json with the same target write name will be erased automatically.
接下来,我们再次使用 'with open()' 语法和 'w' 选项。'w' 是一种写入模式,可让我们编辑新信息并将新信息写入文件。这是对我们有用的捕获 ::: 任何具有相同目标写入名称的现有 json 都将被自动删除。
So what we can do now, is simply write to the same filename with the new data
所以我们现在可以做的就是将新数据写入相同的文件名
# add the id key-value pair (rmbr that it already has the "name" key value)
json_content["id"] = "134"
with open(PATH_TO_JSON,'w') as jsonfile:
json.dump(json_content, jsonfile, indent=4) # you decide the indentation level
And there you go! data.json should be good to go for an good old POST request
你去吧!data.json 应该很适合处理一个很好的旧 POST 请求
回答by abdo Information
try this script:
试试这个脚本:
with open("data.json") as f:
data = json.load(f)
data["id"] = 134
json.dump(data, open("data.json", "w"), indent = 4)
the result is:
结果是:
{
"name":"mynamme",
"id":134
}
Just the arrangement is different, You can solve the problem by converting the "data" type to a list, then arranging it as you wish, then returning it and saving the file, like that:
只是排列方式不同,您可以通过将“数据”类型转换为列表,然后根据需要进行排列,然后返回并保存文件来解决问题,如下所示:
index_add = 0
with open("data.json") as f:
data = json.load(f)
data_li = [[k, v] for k, v in data.items()]
data_li.insert(index_add, ["id", 134])
data = {data_li[i][0]:data_li[i][1] for i in range(0, len(data_li))}
json.dump(data, open("data.json", "w"), indent = 4)
the result is:
结果是:
{
"id":134,
"name":"myname"
}
you can add if condition in order not to repeat the key, just change it, like that:
您可以添加 if 条件以免重复键,只需更改它,如下所示:
index_add = 0
n_k = "id"
n_v = 134
with open("data.json") as f:
data = json.load(f)
if n_k in data:
data[n_k] = n_v
else:
data_li = [[k, v] for k, v in data.items()]
data_li.insert(index_add, [n_k, n_v])
data = {data_li[i][0]:data_li[i][1] for i in range(0, len(data_li))}
json.dump(data, open("data.json", "w"), indent = 4)

