我想更新字典/json 键而不是附加一个新键?

Posted

技术标签:

【中文标题】我想更新字典/json 键而不是附加一个新键?【英文标题】:I want to update a dictionary/json key instead of appending a new one? 【发布时间】:2020-05-06 03:50:09 【问题描述】:

好的,所以我正在使用 discord.py 和 JSON,并且我正在尝试制作票务计数器,客户端拒绝使用数据库,所以我必须使用 JSON。但是每次代码更新文件时,它都会创建第二个密钥,然后使用该密钥而不是第一个密钥。如果有人想看到它在行动中发生,请给我朋友 (Jpac14#8237),我会告诉你会发生什么。我还将附上我的代码和 JSON 文件。

您也认为我可以为您提供收藏模块吗?

代码:

from discord.ext import commands
import discord
import json

class TicketSystem(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.create_ticket_msgs = []

    @commands.Cog.listener()
    async def on_reaction_add(self, reaction, user):
        for create_ticket_msg in self.create_ticket_msgs:
            if reaction.message.id == create_ticket_msg.id and user != self.bot.user:
                await reaction.message.channel.send(f"user reacted")
                await reaction.message.remove_reaction("????", user)

                ticket_counter_dict = 

                try:
                    with open("json/ticket_counter.json", "r") as ticket_counter_json:
                        ticket_counter_dict = json.load(ticket_counter_json)
                except json.JSONDecodeError:
                    print("JSONDecodeError")

                current_ticket_counter = ticket_counter_dict.get(str(reaction.message.guild.id))

                if current_ticket_counter == None:
                    current_ticket_counter = 1

                ticket_catergory = discord.utils.get(reaction.message.guild.categories, name="Tickets")

                if reaction.message.guild.id == 660156957486874645:
                    support_team_role = discord.utils.get(reaction.message.guild.roles, name="Staff")
                else:
                    support_team_role = discord.utils.get(reaction.message.guild.roles, name="Support")

                ticket_channel_overwrites = 
                    support_team_role: discord.PermissionOverwrite(read_messages=True),
                    user: discord.PermissionOverwrite(read_messages=True),
                    reaction.message.guild.default_role: discord.PermissionOverwrite(read_messages=False)
                

                users_ticket_channel = await ticket_catergory.create_text_channel(f"ticket-current_ticket_counter", overwrites=ticket_channel_overwrites)

                current_ticket_counter += 1

                ticket_counter_dict.update(reaction.message.guild.id: current_ticket_counter)

                with open("json/ticket_counter.json", "w") as ticket_counter_json:
                    json.dump(ticket_counter_dict, ticket_counter_json)

                embedMessage = discord.Embed(description="Support will be with you shortly.\nTo close the ticket type ?close", color=discord.colour.Colour.green())
                embedMessage.set_footer(text=f"Created By Nexus Developments - https://discord.gg/YmdugDf", icon_url="https://i.imgur.com/MRBsIpe.png")

                await users_ticket_channel.send(embed=embedMessage)



    @commands.command(name="ticketmsg")
    async def send_create_ticket_msg(self, ctx, channel: discord.TextChannel):
        embedMessage = discord.Embed(title="Create A Ticket", description="To create a ticket react with ????", timestamp=ctx.message.created_at, color=discord.colour.Colour.green())
        embedMessage.set_footer(text=f"Created By Nexus Developments - https://discord.gg/YmdugDf", icon_url="https://i.imgur.com/MRBsIpe.png")

        create_ticket_msg = await channel.send(embed=embedMessage)
        await create_ticket_msg.add_reaction("????")

        self.create_ticket_msgs.append(create_ticket_msg)


def setup(bot):
    bot.add_cog(TicketSystem(bot))

JSON 文件:

"665930890039394305": 6, "665930890039394305": 7

【问题讨论】:

这说明了json 模块的一个非常有趣的警告 【参考方案1】:

reaction.message.guild.id 是一个int

当您编写ticket_counter_dict.update(reaction.message.guild.id: current_ticket_counter) 时,您会在您的字典中创建一个新的int 键,它不会覆盖加载json 文件时存在的str 键。

看这个例子:

import json
d = 1: 'a', '1': 'b'
json.dumps(d)
>>> '"1": "b", "1": "a"'

dict 可以同时保存1'1' 作为键,因为它们是不同的对象。但是json序列化会将两者都变成字符串,因为json使用字符串作为键。

我认为 json 模块还有改进的空间,因为它似乎没有检查字符串化的键是否都是唯一的。

您可以通过确保在字典中使用字符串作为键来修复代码:

ticket_counter_dict.update(str(reaction.message.guild.id): current_ticket_counter)

【讨论】:

我可以使用dictionary[str(key)] = value,它也可以吗?

以上是关于我想更新字典/json 键而不是附加一个新键?的主要内容,如果未能解决你的问题,请参考以下文章

Python JSON转储/附加到.txt,每个变量都在新行

如何将浮点值附加为字典中的浮点数?

如何更新字典,以便如果键'a'的值为'c'而不是'c'的键,则附加值'a'?

如何将字典附加到熊猫数据框?

用循环附加到字典

附加到嵌套 JSON 字典的顶部 [重复]