Python 为什么我的Discord bot无法在JSON文件中正确打开或存储内容?

Python 为什么我的Discord bot无法在JSON文件中正确打开或存储内容?,python,json,discord,discord.py,Python,Json,Discord,Discord.py,我目前正在创建一个反应角色事件。在那里,您可以通过命令设置反应角色。格式为:>reactions@role messageID emote。然后,机器人会将反应添加到给定的消息中。 (您在邮件上使用给定的表情进行反应并获得角色。取消反应将删除该角色。) 因此,我将所有内容都存储在一个JSON文件中。格式可以在代码中看到。它工作得非常好。重新启动机器人后,所有内容似乎都未存储/当我单击反应时,什么都没有发生。但是,所有内容似乎仍存储在JSON文件中,但没有使用它。 到目前为止,我的代码是: cla

我目前正在创建一个反应角色事件。在那里,您可以通过命令设置反应角色。格式为:
>reactions@role messageID emote
。然后,机器人会将反应添加到给定的消息中。
(您在邮件上使用给定的表情进行反应并获得角色。取消反应将删除该角色。) 因此,我将所有内容都存储在一个JSON文件中。格式可以在代码中看到。它工作得非常好。重新启动机器人后,所有内容似乎都未存储/当我单击反应时,什么都没有发生。但是,所有内容似乎仍存储在JSON文件中,但没有使用它。 到目前为止,我的代码是:

class ReactionRoles(commands.Cog):
    """
    This instance handles all reaction role events.
    """

    def __init__(self, bot):
        super().__init__()
        self.bot = bot
        self.reaction_roles = []

    @commands.command(name="Reaction", aliases=["reactionss"])
    async def set_reaction(self, ctx, role: discord.Role = None, msg: discord.Message = None, emoji=None):
        with open('reaction_roles.json', 'r', encoding='utf-8') as f:
            reaction_roles = json.load(f)

        try:
            reaction_roles[f"{role.id}, {msg.id}"] = emoji
        except KeyError:
            new = {ctx.message.id: role.id}
            reaction_roles.update(new)

        if role is not None and msg is not None and emoji is not None:
            await msg.add_reaction(emoji)
            self.reaction_roles.append((role.id, msg.id, str(emoji.encode("utf-8"))))

            with open('reaction_roles.json', 'w', encoding='utf-8') as f:
                json.dump(reaction_roles, f, indent=2)

            await ctx.channel.send("**Reaction has been set.**")

    @commands.Cog.listener()
    async def on_raw_reaction_add(self, payload):
        for role_id, msg_id, emoji in self.reaction_roles:
            if msg_id == payload.message_id and emoji == str(payload.emoji.name.encode("utf-8")):
                await payload.member.add_roles(self.bot.get_guild(payload.guild_id).get_role(role_id))

    @commands.Cog.listener()
    async def on_raw_reaction_remove(self, payload):
        for role_id, msg_id, emoji in self.reaction_roles:
            if msg_id == payload.message_id and emoji == str(payload.emoji.name.encode("utf-8")):
                guild = self.bot.get_guild(payload.guild_id)
                await guild.get_member(payload.user_id).remove_roles(guild.get_role(role_id))```

重置后它不起作用的原因是,每次重置时,它都会重新定义
reaction\u roles
列表并将其设置为空

def\uuuu初始化(self,bot):
super()。\uuuu init\uuuuu()
self.bot=bot
self.reaction_roles=[]#每当重新加载代码时,该值都在此处设置,并且为空
您的
on_raw_reaction_add
on_raw_reaction_remove
使用此列表来确定反应和角色,而不是JSON文件

您可以这样做,只使用dicts和JSON文件。JSON不支持整数作为键,因此任何时候使用msg.id时,都要使用str(msg.id)

#实际上没有必要,但我们需要多次读取该文件
#如果重新定位,只需编辑一次
def json_open():#您可以重命名它,只需记住更改其余部分即可
将open('reaction_roles.json','r',encoding='utf-8')作为f:
reaction_roles=json.load(f)
返回反应单元角色
类反应(commands.Cog):
"""
此实例处理所有反应角色事件。
"""
def uuu init uuuu(自我,机器人):
super()。\uuuu init\uuuuu()
self.bot=bot
@commands.command(name=“Reaction”,别名=[“reactions”])
异步def set_反应(self、ctx、role:discord.role=None、msg:discord.Message=None、emoji=None):
reaction_roles=json_open()#打开json文件
#第一次将表情符号注册到msg会出现错误,因为msg不在dict中
尝试:
role\u dict=反应\u角色[str(msg.id)]
除:
角色_dict={}
role_dict[emoji]=role.id
反应角色[str(msg.id)]=角色指令
如果角色不是None,msg不是None,表情符号不是None:
等待消息添加反应(表情符号)
将open('reaction_roles.json','w',encoding='utf-8')作为f:
dump(reaction\u roles,f,indent=2,确保\u ascii=False)
#设置sure_ascii=False-->我们可以使用json中的实际表情
等待ctx.channel.send(“**已设置反应。**”)
#接下来的两个步骤是相同的,除了一个是删除,一个是添加
@commands.Cog.listener()
原始反应添加上的异步定义(自身,有效负载):
如果payload.user_id==775390992777216040:#Bot不会意外获得任何角色
返回
reaction_roles=json_open()#open json
如果列表中的str(payload.message_id)(reaction_roles.keys()):#如果消息匹配
role_dict=反应_roles[str(payload.message_id)]#如果反应匹配
如果列表中的payload.emoji.name(role_dict.keys()):
role\u id=role\u dict[payload.emoji.name]
guild=self.client.get\u guild(payload.guild\u id)
角色=帮会。获取角色(角色id)
等待公会。获取成员(有效载荷。用户id)。添加角色(角色)
@commands.Cog.listener()
异步def on_raw_reaction_remove(自身,有效负载):
如果payload.user_id==775390992777216040:
返回
反应\u角色=json\u开放()
如果列表(reaction_roles.keys())中的str(payload.message_id):
role\u dict=反应\u角色[str(payload.message\u id)]
如果列表中的payload.emoji.name(role_dict.keys()):
role\u id=role\u dict[payload.emoji.name]
guild=self.client.get\u guild(payload.guild\u id)
角色=帮会。获取角色(角色id)
等待公会。获取成员(有效负载。用户id)。删除角色(角色)
JSON文件将以如下方式结束

{
“msg1_id”:{

“谢谢,在我使用命令时,我们需要为“json_open”做什么?我是否只需要将其设置为:
reaction_roles=self.bot.json_open()
?@Dominik您不需要对它做任何事情。我之所以将其放在那里,是因为当我们需要打开
reaction_roles.json
文件时(我们只在这段代码中打开它三次)我们可以做
reaction\u roles=json\u open()
是一个函数,每次调用它时,它都会打开json文件并返回我们可以使用的
reaction\u roles
。我在类之前,在代码的最顶端定义它。现在如果更改文件名或位置,只需在顶部编辑一次,而不是在代码中编辑三次