【问题标题】:Python variable exists undefined?Python变量存在未定义?
【发布时间】:2021-10-09 20:56:47
【问题描述】:

我无法创建一个简单的开/关开关。 我是初学者,正在编写一个不和谐的机器人来娱乐和学习。我的机器人在不止一台服务器上,这就是为什么全局变量不是一个选项的原因(在一台服务器上运行它也会为其他服务器更改它)。 将变量放入命令中不是一种选择,因为每次我运行命令时,它都会定义它。 我需要一些存在但只能由子流程定义的东西。

@bot.command()
async def xxx(ctx):

    # global x # doesn't work correctly
    # x = "" # doesn't work correctly

    if x != True:
        x = True
        await ctx.send("X is on!")
 
    else:
        x = False
        await ctx.send("X is off!")


    while x == True:
        #some code calculations here, blablabla

    await asyncio.sleep(60)

我的问题有什么解决方案? 谢谢。

【问题讨论】:

  • 您对函数 def x() 和变量 x = ... 使用相同的名称 - 这会产生很大的问题。
  • 对不起,这是一个例子我实际上没有使用相同的名字,现在编辑,改为def xxx()
  • 也许你应该使用带有服务器名称的字典if x["server name"] is not True:
  • 绝对值得研究,但乍一看 - 如果我将机器人公开,我无法跟踪所有服务器以放入字典、代码
  • 您不必在开始时添加所有服务器 - 您可以检查运行此功能的服务器,如果字典中不存在则将其添加到字典中。 if 'server name' not in x: x["server name"] = True

标签: python variables discord undefined exists


【解决方案1】:

我假设server 表示ctx.guild - 因此您可以使用字典来保存不同服务器的值 - x[ctx.guild.name]x[ctx.guild]

您不必在开始时创建所有服务器,但如果服务器在字典中,您可以检查函数并添加默认值。

# global dictionary
x = dict()

@bot.command()
async def xxx(ctx):
    # dictionary doesn't need `global x` in function

    server_name = ctx.guild.name
    
    # set default value if used first time on server/guild
    if server_name not in x:
        x[server_name] = False
        
    if not x[server_name]:
        x[server_name] = True
        await ctx.send("X is on!")
    else:
        x[server_name] = False
        await ctx.send("X is off!")

    while x[server_name]:
        #some code calculations here, blablabla

    await asyncio.sleep(60)

你也可以使用not切换True/False

x[server_name] = not x[server_name]

if x[server_name]:
    await ctx.send("X is on!")
else:
    await ctx.send("X is off!")

【讨论】:

  • 谢谢!我现在正在取得进展;)
【解决方案2】:

您可以尝试将此代码包装在一个对象中并将 X 声明为类变量 IE

class ChatBot(object):
    x = False

    @classmethod
    @bot.command()
    def xxx(ctx):
        if x != True:
            x = True
            await ctx.send("X is on!")

        else:
            x = False
            await ctx.send("X is off!")


        while x == True:
            #some code calculations here, blablabla

        await asyncio.sleep(60)

面向对象的编程使大量的事情更容易在 python 中实现和调试,另外一个好处是不用担心全局变量(通常最好避免使用单例,除非你绝对需要它们 - IE 日志记录或配置)。祝你好运 - 从长远来看,命名变量和函数也很重要,所以我建议你尽早养成习惯!

【讨论】:

    【解决方案3】:

    您必须将开关设置在起始位置。你如何做到这一点取决于你。我会亲自创建一个开关类。您的简单解决方案是在函数外部全局设置起始位置。示例:

    global x
    x = 0
    @bot.command()
    async def x(ctx):
    
        if x != True:
            x = True
            await ctx.send("X is on!")
     
        else:
            x = False
            await ctx.send("X is off!")
    
        while x == True:
            #some code calculations here, blablabla
    
        await asyncio.sleep(60)
    

    【讨论】:

    • 所有在函数外部创建的变量都是全局的,您不必使用global x 外部函数。您必须在函数内部使用global x 来更改此全局变量的值。没有globla x,它仍然会创建局部变量。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 2011-04-29
    • 2018-11-21
    • 2017-02-07
    • 1970-01-01
    相关资源
    最近更新 更多