Discord.py 变量在整个代码中不是恒定的
问题描述
我目前正在使用 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_message
event
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_message
event
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
相关文章