【问题标题】:Why is discord.py not recognizing variables outside "on_message()"?为什么 discord.py 不能识别“on_message()”之外的变量?
【发布时间】:2020-12-09 09:31:21
【问题描述】:

我的 discord.py 脚本给了我一个意外错误。它基本上将我在async def on_message(): 之外定义但在其下使用的所有变量标记为“未定义”。

好吧,您也可以通过在on_message() 下定义它们来轻松修复它。我试过了。 但是,问题来了:每次发送消息时,变量都会被设置回您定义的值,即使您确实添加了,就像一行说如果发生这种情况,请将其更改为另一个值。 (例如前缀,正如您在下面的代码中看到的那样,我想使用名为“changeprefix”的命令更改机器人的前缀并且它可以工作,但是当使用该前缀发送另一条消息时,它不会识别它;因为在开头定义变量的行再次运行,一切都被重置了。

除了删除on_message() 并使用discord.ext.commands 或其他方法之外,还有其他方法吗?我对on-message()系统比较熟悉,而且如果我切换到它,我会更改整个脚本。

import discord

client = discord.Client()
token= "some nice token"
#defining here results in "UnboundLocalError: local variable 'prefix' referenced before assignment", in the first line using the variable defined here

@client.event

async def on_message(message):
     #defining here results variables being refreshed each time a message is sent

【问题讨论】:

    标签: python discord undefined discord.py


    【解决方案1】:

    我相信您正在寻找的是global 这是一个简单的使用示例。

    something = 1
    
    @client.event
    async def on_message(message):
        global something
        something = something + 1
        print(something) # 2 at first iteration
    
    #outside of on_message
    print(something) # 2 it is the same
    

    如果您想使用前缀,请将其设置为以guild.id 为键的字典,值为前缀。

    顺便说一句,使用命令会更容易做到这一点。

    注意:如果您重新启动机器人,您将丢失此信息

    【讨论】:

    • 我希望变量不会像在 on_message 中那样不断更新。我猜你展示的是,在函数内部定义它,但也让它成为全局的,这样即使你在外面提到它,它也会被算作一个变量。
    • 你是对的。几个月后我随机发现了这个问题,并重新阅读了您的答案。我当时认为这是为了在任何声明都是本地的地方定义全局变量。但据我了解,它是指已创建的全局变量。我的想法已经不那么合乎逻辑了,而您已经可以在这样的地方之外创建全局变量。抱歉误导。
    • 还有,你有什么建议可以防止你在最后提到的情况?我认为每次运行代码时都会重新初始化所有内容的任何脚本都会发生这种情况。也许我可以使用另一个文件来存储当前设备的信息,以及用于多个设备的数据库/服务器。
    【解决方案2】:

    如果我正确理解了您的问题,您需要一个在每次调用命令时都会更改其值的变量,您可以使用全局变量(我不推荐它)或机器人变量。也可以使用commands.Bot,这样你就可以使用命令系统了

    bot = commands.Bot(command_prefix='.')
    
    # Using a global variable
    my_var = 'my value'
    
    @bot.command()
    async def foo(ctx, arg):
        global my_var
        my_var = arg
        await ctx.send(f"Changed `my_var` value to `arg`")
    
    # Using a bot var
    bot.my_var = 'my value'
    
    @bot.command()
    async def foo(ctx, arg):
        bot.my_var = arg
        await ctx.send(f"Changed `bot.my_var` value to `arg`")
    

    【讨论】:

    • 我希望变量不会像在 on_message 中那样不断更新。我猜你展示的是,在函数内部定义它,但也让它成为全局的,这样即使你在外面提到它,它也会被算作一个变量。
    • 你是对的。几个月后我随机发现了这个问题,并重新阅读了您的答案。我当时认为 global 关键字用于在任何声明都是本地的地方定义全局变量。但据我了解,它是指已创建的全局变量。我的想法已经不那么合乎逻辑了,而您已经可以在这样的地方之外创建全局变量。对于机器人命令部分,当我第一次找到你的答案时,我什至没有看到它。抱歉误导。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-09
    • 2015-12-25
    • 1970-01-01
    相关资源
    最近更新 更多