从JSON Python中删除元素

从JSON Python中删除元素,python,json,python-3.x,dictionary,discord.py,Python,Json,Python 3.x,Dictionary,Discord.py,我正试图为我的discord机器人发出一个命令,从服务器上删除一个所谓的“派系”。派系存储在一个整洁的JSON中,如下所示 { "Meme Faction": { "members": [], "owner": 429935667737264139, "description": "This is the description :smile:&quo

我正试图为我的discord机器人发出一个命令,从服务器上删除一个所谓的“派系”。派系存储在一个整洁的JSON中,如下所示

{
    "Meme Faction": {
        "members": [],
        "owner": 429935667737264139,
        "description": "This is the description :smile:",
        "member role": 773580603072839710,
        "owner role": 773580603605516290
    },
    "Gamer Faction": {
        "members": [],
        "owner": 429935667737264139,
        "description": "This is the description :smile:",
        "member role": 773580603072839710,
        "owner role": 773580603605516290
    }
}
下面是应该删除一个派系的代码:

@commands.command(aliases=["d"])
async def delete(self, ctx, *, name: str):
    with open("configs/factions.json", "r+") as f:
        factions_json = json.load(f)
        factions_list = list(factions_json.keys()) # loads JSON keys as list

        name_capital = name.title()
        if name_capital in factions_list:
            member_role = ctx.guild.get_role(factions_json[name_capital]["member role"])
            owner_role = ctx.guild.get_role(factions_json[name_capital]["owner role"]) 

            await member_role.delete() # deletes faction role
            await owner_role.delete() # deletes faction owner role

            # JSON remove code
            factions_json.pop(name_capital) 
            f.seek(0)
            json.dump(factions_json, f, indent=4)

            await ctx.message.add_reaction("✅")
问题是,它不是从JSON中删除派系,而是在JSON的另一个版本的末尾附加不带派系的内容。像这样:

{
    "Meme Faction": {
        "members": [],
        "owner": 429935667737264139,
        "description": "This is the description :smile:",
        "member role": 773580603072839710,
        "owner role": 773580603605516290
    },
    "Gamer Faction": {
        "members": [],
        "owner": 429935667737264139,
        "description": "This is the description :smile:",
        "member role": 773580603072839710,
        "owner role": 773580603605516290
    }
}{
    "Meme Faction": {
        "members": [],
        "owner": 429935667737264139,
        "description": "This is the description :smile:",
        "member role": 773580603072839710,
        "owner role": 773580603605516290
    },
}

如何覆盖JSON而不是附加到它?

当您在模式
r+
下打开文件时,您可以打开它进行读写

然后,读取文件,使流位置移动到文件的末尾

然后,写入文件,使其在当前流位置(即文件的结尾)写入

要解决此问题,您有两个选项:

备选案文1: 使用
f.seek(0)
返回文件的开头。然后写入该文件。问题是,它只会覆盖转储新json所需的文件。文件的其余部分不会被覆盖,因此不管怎样,最终还是会得到乱码的json。要修复此问题,您需要截断文件的其余部分

以open('派系.json','r+')作为f的
:
j=json.load(f)
j、 流行音乐(“模因派”)
f、 搜索(0)
dump(j,f,indent=4)
f、 截断()
给出输出:

{
“玩家派系”:{
“成员”:[…],
“所有者”:429935667737264139,
“描述”:“这是描述:微笑:”,
“成员角色”:773580603072839710,
“所有者角色”:773580603605516290
}
}
选择2 关闭原始文件句柄,然后打开一个新的文件句柄,仅用于写操作。然后写入该文件

以open('派系.json','r+')作为f的
:
j=json.load(f)
j、 流行音乐(“模因派”)
以open('派系.json','w')作为f:
dump(j,f,indent=4)
给出输出:

{
“玩家派系”:{
“成员”:[…],
“所有者”:429935667737264139,
“描述”:“这是描述:微笑:”,
“成员角色”:773580603072839710,
“所有者角色”:773580603605516290
}
}

当您在
r+
模式下打开文件时,您可以打开它进行读写

然后,读取文件,使流位置移动到文件的末尾

然后,写入文件,使其在当前流位置(即文件的结尾)写入

要解决此问题,您有两个选项:

备选案文1: 使用
f.seek(0)
返回文件的开头。然后写入该文件。问题是,它只会覆盖转储新json所需的文件。文件的其余部分不会被覆盖,因此不管怎样,最终还是会得到乱码的json。要修复此问题,您需要截断文件的其余部分

以open('派系.json','r+')作为f的
:
j=json.load(f)
j、 流行音乐(“模因派”)
f、 搜索(0)
dump(j,f,indent=4)
f、 截断()
给出输出:

{
“玩家派系”:{
“成员”:[…],
“所有者”:429935667737264139,
“描述”:“这是描述:微笑:”,
“成员角色”:773580603072839710,
“所有者角色”:773580603605516290
}
}
选择2 关闭原始文件句柄,然后打开一个新的文件句柄,仅用于写操作。然后写入该文件

以open('派系.json','r+')作为f的
:
j=json.load(f)
j、 流行音乐(“模因派”)
以open('派系.json','w')作为f:
dump(j,f,indent=4)
给出输出:

{
“玩家派系”:{
“成员”:[…],
“所有者”:429935667737264139,
“描述”:“这是描述:微笑:”,
“成员角色”:773580603072839710,
“所有者角色”:773580603605516290
}
}

OP已经在使用您的“选项1”,因此这并不能回答问题。这就是为什么会有选项2。我仍在充实备选方案1。耐心点,蚱蜢!:)您可以在写入后调用
f.truncate()
,以删除文件中的额外数据,但我认为像您建议的那样打开单独的读写文件处理程序是最好的方法。选项1应该仍然有效。但据OP报道,情况并非如此。“不,你还没有回答这个问题。”马特菲克说,“是的,我在信中加了这个。必须查找调用的函数,以确保.OP已在使用您的“选项1”,因此这并不能回答问题。这就是为什么会有选项2。我仍在充实备选方案1。耐心点,蚱蜢!:)您可以在写入后调用
f.truncate()
,以删除文件中的额外数据,但我认为像您建议的那样打开单独的读写文件处理程序是最好的方法。选项1应该仍然有效。但据OP报道,情况并非如此。“不,你还没有回答这个问题。”马特菲克说,“是的,我在信中加了这个。必须查找调用了什么函数才能确保。