Python 读取 JSON 文件并修改

嗨,我正在尝试从一个 json 文件获取数据,然后插入和 id,然后执行 POSTREST。 我的文件资料 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 值。

192542 次浏览

使用 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

Falsetru 的解决方案不错,但有一个小缺陷:

假设原始“ id”长度大于5个字符。然后,当我们使用新的‘ id’(只有3个字符的134)转储时,从文件中的位置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)

我想展示一下瓦迪姆解决方案的修改版本。它有助于处理写/修改 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)

实际上有相当多的方法可以做到这一点,以上所有方法都是一种或另一种有效的方法... ... 让我添加一个直截了当的命题。所以假设您当前现有的 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'

接下来,我们再次使用带有‘ w’选项的‘ with open ()’语法。‘ 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

就是这样! Json 应该可以很好地处理旧的 POST 请求

试试这个脚本:

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)

这种执行应该足够了:

with open(jsonfile, 'r') as file:
data = json.load(file)
data[id] = value


with open(jsonfile, 'w') as file:
json.dump(data, file)

使用上下文管理器打开 jsonfile。 Data 保存更新后的对象,并以‘ w’模式转储到覆盖的 jsonfile 中。

不完全是你的解决方案,但可能有助于一些人解决这个问题的钥匙。 我有文件夹里的文件清单,我得让 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"
}
]
}