Unound LocalError:局部变量在赋值之前被引用,但它是全局变量

2022-04-10 00:00:00 python discord.py variables global local

问题描述

我正在用discord.py制作一个Python Discord机器人。我对Python比较陌生,但在其他语言方面有大约八年的经验。我的问题是,即使我将prefix定义为全局变量,我也会得到UnboundLocalError: local variable 'prefix' referenced before assignment。(我使用的是Python3.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

这是因为当您为作用域中的变量赋值时, 该变量变为该作用域的局部变量,并以任何类似方式隐藏 外部作用域中的命名变量。

简写:

您需要在函数的作用域之外声明全局变量,例如

#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。

每个模块都有自己的专用符号表,用作 模块中定义的所有函数的全局符号表。因此, 模块的作者可以在模块中使用全局变量,而无需 担心与用户的全局变量发生意外冲突。

因此,当您运行bot脚本时,Python会将其视为作为主脚本运行的模块,并具有自己的全局作用域。
在全局作用域中声明变量时,若要在某些函数的局部作用域中使用它,需要使用关键字global来访问模块的该全局作用域。

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

相关文章