"UnboundLocalError: local variable 'x' referenced before assignment" But it's a global variable

"UnboundLocalError: local variable 'x' referenced before assignment" But it's a global variable

我正在用 discord.py 制作一个 Python Discord 机器人。我对 Python 比较陌生,但有大约八年的其他语言经验。我的问题是,即使我已将 prefix 定义为全局变量,我仍然得到了 UnboundLocalError: local variable 'prefix' referenced before assignment。 (我正在使用 Python 3.6.8)

我尝试在 on_ready 函数之外定义变量,但我得到了相同的结果。

import discord;

client = discord.Client();

@client.event
async def on_ready():
  print('Loading complete!')
  ...
  global prefix
  prefix = 'hello world'

@client.event
async def on_message(message):

  if message.author == client.user:
    return

  messageContents = message.content.lower()
  splitMessage = messageContents.split()
  try:
    splitMessage[0] = splitMessage[0].upper()lower()
  except:
    return
  if splitMessage[0]==prefix:
    ...
    (later in that if statement and a few nested ones)
    prefix = newPref

client.run('token')

我预计输出是 运行 if 语句中的代码,但我得到错误 UnboundLocalError: local variable 'prefix' referenced before assignment 并且没有代码是 运行.

我唯一能想到的问题是prefix = newpref。我试过了:

global prefix
prefix = newpref

但后来我收到错误:SyntaxError: name 'prefix' is used prior to global declaration 并且机器人根本没有启动。我应该怎么办?

根据 official docs

This is because when you make an assignment to a variable in a scope, that variable becomes local to that scope and shadows any similarly named variable in the outer scope.

短版:

您需要在您的函数范围之外声明您的全局变量,例如

#declaring the global variable
x = 10
def foobar():
    #accessing the outer scope variable by declaring it global
    global x
    #modifying the global variable
    x+=1
    print(x)
#calling the function
foobar()

长版:

基本上,python 中的所有内容都是一个对象,这些对象的集合称为 namespaces

Each module has its own private symbol table, which is used as the global symbol table by all functions defined in the module. Thus, the author of a module can use global variables in the module without worrying about accidental clashes with a user’s global variables.

因此,当您 运行 您的 bot 脚本时,python 将其视为一个 运行ning 作为主脚本的模块,具有自己的全局范围。
当您在全局范围内声明变量时,要在某些函数的局部范围内使用它,您需要使用关键字 global 来访问模块的全局范围。

此外,python 不需要 分号来终止语句(例如client = discord.Client();)。如果您希望将多个语句放在同一行,可以使用分号 来分隔语句。