问题描述
我目前正在使用 discord.py 开发一个机器人,在这种情况下使用 JSON 文件来存储它所在的每个服务器的机器人前缀.(+ 是机器人的默认前缀)使用前缀,我正在做 4 件事:在公会加入时:向 JSON 文档添加前缀On guild remove:从 JSON 文档中删除此公会的前缀+更改前缀当提到机器人时,它会输出一条消息,说明:'你好,这个服务器的前缀是+'
I am currently developing a bot using discord.py and in this case using a JSON file to store the bots prefixes for each server that it is in. ( + is the bots default prefix ) With prefixes, there is 4 things I am doing: On guild join: Adds a prefix to the JSON document On guild remove: Removes the prefix for this guild from the JSON document +changeprefix and when the bot is mentioned, it outputs a message stating: 'Hello, the prefix for this server is +'
前 3 部分工作正常.但是,当提到该机器人时,它会输出错误:
The first 3 parts work correctly. However, when the bot is mentioned it outputs the error:
await message.channel.send(f'Hi my prefix for this server is **{prefix}**) NameError: name 'prefix' is not defined
我已经做了一些研究,并就这个问题询问了多个帮助服务器,但是我发现 python 没有在这种情况下有用的常量,帮助服务器上的人不确定这个问题的答案.
I have done some research and asked multiple help servers about this issue however what I have found is that python does not have constants which would be useful in this situation and people on help servers were unsure of the answer to this question.
前缀设置的所有部分的代码是这样的:
The code for all parts of the prefix setup is this:
@bot.event async def on_guild_join(guild): with open('prefix.json', 'r') as f: prefixes = json.load(f) prefixes[str(guild.id)] = '+' prefixes = prefix with open('prefix.json', 'w') as f: json.dump(prefixes, f, indent=4) # REMOVES PREFIX FROM JSON FILE @bot.event async def on_guild_remove(guild): with open('prefix.json', 'r') as f: prefixes = json.load(f) prefixes.pop(str(guild.id)) with open('prefix.json', 'w') as f: json.dump(prefixes, f, indent=4) # COMMAND TO CHANGE THE PREFIX @bot.command() @commands.has_permissions(manage_messages=True) async def changeprefix(ctx, prefix): with open('prefix.json', 'r') as f: prefixes = json.load(f) prefixes[str(ctx.guild.id)] = prefix prefix = prefix with open('prefix.json', 'w') as f: json.dump(prefixes, f, indent=4) await ctx.send(f'Prefix changed to **{prefix}**')
错误来自的on_message是这样的:
@bot.event async def on_message(message): if message.content.startswith("<@bot ID>"): await message.channel.send(f'Hi my prefix for this server is **{prefix}**') await bot.process_commands(message)
这在代码中比其他部分更靠后
and this is further down in the code than the other parts of this
任何帮助将不胜感激.预期的输出是,当它标记的机器人时,它会发送一条消息,说明服务器的当前前缀.
Any help would be appreciated. The expected output is so when the bot it tagged, it sends a message saying the current prefix for the server.
更新正如下面评论中提到的,我已经更新了我的代码,以便它读取 JSON 文件并检索前缀.这是 on_messageevent
Update As mentioned in a comment below, I have updated my code so it reads the JSON file and retrieves the prefix. This is the updated code in the on_messageevent
if message.content.startswith("<bot ID>"): with open('prefix.json', 'r') as f: prefixes = json.load(f) prefixes[str(ctx.guild.id)] = prefix await message.channel.send(f'Hi my prefix for this server is **{prefix}**')
但是,这仍然显示
NameError: name 'prefix' is not defined
我尝试过的其他方法我也尝试像这样定义 prefix:
Other things I have tried I also tried defining prefix like this:
if message.content.startswith("<@850794452364951554>"): with open('prefix.json', 'r') as f: prefixes = json.load(f) prefixes[str(ctx.guild.id)] = prefix prefix = prefix await message.channel.send(f'Hi my prefix for this server is **{prefix}**')
我在 prefixes[str(ctx.guild.id)] = prefix
在这两种情况下,它都会输出以下错误:
In both those cases, it outputs this error:
UnboundLocalError: local variable 'prefix' referenced before assignment
推荐答案
你的代码在很多地方对我来说毫无意义,因为你在 message 事件中使用了 ctx, 这起初是不可能的.此外,在复制代码时,prefixes = prefix 出现错误,因此值得怀疑的是为什么这对您有效.
Your code makes no sense to me in many places, because you use ctx in a message event, which is not possible at first. Also, when copying the code, I get an error with prefixes = prefix, so it is questionable why this supposedly works for you.
您的 on_guild_join 对我来说也毫无意义,因为每个人都有默认前缀.该事件可能与您的 changeprefix 命令相关,但可以做得更好.
Your on_guild_join also makes no sense to me, because everyone has the default prefix. The event may be relevant for your changeprefix command, but that can be done better.
我稍微重写了您的 changeprefix 命令并调整了您的 on_message 事件.
I rewrote your changeprefix command a bit and adjusted your on_message event.
看看下面的代码:
@bot.event async def on_message(message): if message.content.startswith("What is the prefix for this guild?"): with open('prefix.json', 'r', encoding='utf-8') as fp: custom_prefixes = json.load(fp) try: prefix = custom_prefixes[f"{message.guild.id}"] await message.channel.send(f'Hi my prefix for this server is **{prefix}**') except KeyError: return await message.channel.send("You have not set a new prefix.") # No JSON entry await bot.process_commands(message) @bot.command() async def setprefix(ctx, prefixes: str): with open('prefix.json', 'r', encoding='utf-8') as fp: custom_prefixes = json.load(fp) try: custom_prefixes[f"{ctx.guild.id}"] = prefixes # If the guild.id already exists except KeyError: # If there is no JSON entry new = {ctx.guild.id: prefixes} # New prefix with command input custom_prefixes.update(new) # Add guild.id and prefix await ctx.send(f"Prefix set to: `{prefixes}`") with open('prefix.json', 'w', encoding='utf-8') as fpp: json.dump(custom_prefixes, fpp, indent=2)
由于您的 on_guild_join 事件也包含错误,我们必须以不同的方式确定前缀.如果我们将集合 prefix 附加到默认值,我们可以实现这一点.
As your on_guild_join event also contains errors we have to determine the prefix in a different way. We can achieve that if we append the set prefix to the default one.
看看下面的代码:
def determine_prefix(bot, msg): guild = msg.guild base = [DEFAULT_PREFIX] with open('prefix.json', 'r', encoding='utf-8') as fp: # Open the JSON custom_prefixes = json.load(fp) # Load the custom prefixes if guild: # If the guild exists try: prefix = custom_prefixes[f"{guild.id}"] # Get the prefix base.append(prefix) # Append the new prefix except KeyError: pass return base [...](command.prefix = determine_prefix) # Where you defined your bot