Python读取JSON文件并修改
- 2025-03-20 08:46:00
- admin 原创
- 38
问题描述:
你好,我正在尝试从 json 文件中获取数据并插入 id,然后执行 POST REST。我的文件 data.json 包含:
{
'name':'myname'
}
我想添加一个 id,以便 json 数据如下所示:
{
'id': 134,
'name': 'myname'
}
所以我尝试了:
import json
f = open("data.json","r")
data = f.read()
jsonObj = json.loads(data)
我无法加载 json 格式的文件。我应该怎么做才能将 json 文件转换为 json 对象并添加另一个 id 值。
解决方案 1:
使用 设置项目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
解决方案 2:
falsetru 的解决方案很好,但是有一个小错误:
假设原始“id”长度大于 5 个字符。当我们使用新的“id”(134,只有 3 个字符)进行转储时,从文件中的位置 0 写入的字符串的长度短于原始长度。原始内容中的额外字符(例如“}”)留在文件中。
我通过替换原始文件解决了这个问题。
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)
解决方案 3:
我想介绍 Vadim 解决方案的修改版本。它有助于处理写入/修改 json 文件的异步请求。我知道这不是原始问题的一部分,但可能对其他人有帮助。
如果请求频繁出现,异步文件修改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)
解决方案 4:
确实有很多方法可以做到这一点,以上所有方法都是有效的方法……让我补充一个简单的建议。假设您当前现有的 json 文件如下所示……
{
"name":"myname"
}
并且您想要引入这个新的 json 内容(添加键“id”)
{
"id": "134",
"name": "myname"
}
我的方法一直是让代码具有极高的可读性,并具有易于跟踪的逻辑。因此,首先,我们将整个现有 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'
接下来,我们再次使用“with open()”语法,并带有“w”选项。“w”是一种写入模式,允许我们编辑并将新信息写入文件。以下是对我们有用的提示::任何具有相同目标写入名称的现有 json 都将被自动删除。
所以我们现在能做的就是将新数据写入同一个文件名
# 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
就这样!data.json 应该可以用于传统的 POST 请求
解决方案 5:
这个实现应该足够了:
with open(jsonfile, 'r') as file:
data = json.load(file)
data[id] = value
with open(jsonfile, 'w') as file:
json.dump(data, file)
使用上下文管理器打开 jsonfile。数据保存更新的对象并以“w”模式转储到覆盖的 jsonfile 中。
解决方案 6:
尝试这个脚本:
with open("data.json") as f:
data = json.load(f)
data["id"] = 134
json.dump(data, open("data.json", "w"), indent = 4)
结果是:
{
"name":"mynamme",
"id":134
}
只是安排不同,您可以通过将“数据”类型转换为列表,然后按您希望的方式排列它,然后返回并保存文件来解决问题,如下所示:
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)
结果是:
{
"id":134,
"name":"myname"
}
您可以添加 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)
解决方案 7:
这不是您的解决方案,但可能有助于某些人解决此问题。我在文件夹中有文件列表,我需要使用密钥让 Jason 从中脱颖而出。经过几个小时的尝试,解决方案很简单。
解决方案:
async def return_file_names():
dir_list = os.listdir("./tmp/")
json_dict = {"responseObj":[{"Key": dir_list.index(value),"Value": value} for value in dir_list]}
print(json_dict)
return(json_dict)
响应如下所示:
{
"responseObj": [
{
"Key": 0,
"Value": "bottom_mask.GBS"
},
{
"Key": 1,
"Value": "bottom_copper.GBL"
},
{
"Key": 2,
"Value": "copper.GTL"
},
{
"Key": 3,
"Value": "soldermask.GTS"
},
{
"Key": 4,
"Value": "ncdrill.DRD"
},
{
"Key": 5,
"Value": "silkscreen.GTO"
}
]
}
扫码咨询,免费领取项目管理大礼包!