I am making a Python Discord bot with discord.py. I am relatively new to Python but have about eight years of experience with other languages. My problem is that I get the UnboundLocalError: local variable 'prefix' referenced before assignment
even though I have defined prefix
as a global variable. (I am using Python 3.6.8)
I have tried defining the variables outside the on_ready
function, but I get the same result.
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')
I expected the output would be that it runs the code within the if statement, but instead I get the error UnboundLocalError: local variable 'prefix' referenced before assignment
and no code is run.
The only thing I can think of being the problem is prefix = newpref
. I tried:
global prefix
prefix = newpref
But then I got the error: SyntaxError: name 'prefix' is used prior to global declaration
and the bot didn't start at all. What should I do?
According to the 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.
Short version:
You need to declare your global variable outside the scope of your functions such as
#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()
Long version:
Basically, everything in python is an object and collections of those objects are called 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.
So when you run your bot script, python treats it as a module that is running as the main script, with its own global scope.
When you declare a variable in a global scope, to use it in local scopes of certain functions you need to use the keyword global
to access that global scope of your module.
Also, python does not require semi-colons to terminate statements (such as client = discord.Client();
). Semicolons can be used to delimit statements if you wish to put multiple statements on the same line.