Reputation: 514
So I know this question gets asked a lot, but I haven't found anything that matches exactly what's happening to me.
In my program (Python 3.7.1), on startup I want to define the location where the program is installed, and also a default location where files generated by the program will be saved. Later on in the program, I want to display these variables again, and give the user the option to change the default location to something else.
So I have this code, in the global scope:
import os
installedDirectory = os.getcwd()
os.chdir('C:\\Program Files')
workingDirectory = os.getcwd()
print ('Program install location = ' + installedDirectory)
print ('Working directory = ' + workingDirectory)
The above part of the program works fine, and gives this result:
Program install location = C:\Users\Chuu\AppData\Local\Programs\Python\Python37-32\Scripts Working directory = C:\Program Files
However later in the program, I call these same variables within a function and give the user the option to change the variable workingDirectory:
def hiimafunction():
print ('')
print ('Current program install location = ' + installedDirectory)
print ('')
print ('Current working directory where files are saved = ' + workingDirectory)
print ('')
print ('Where would you like files to be saved?')
print ('')
print ('Press 1 for the current program install location')
print (r'Press 2 for the default startup location - C:\\Program Files')
print ('Press 3 for a custom location')
print ('')
oliviahye = input()
if oliviahye == ('1'):
os.chdir(installedDirectory)
elif oliviahye == ('2'):
os.chdir('C:\\Program Files')
elif oliviahye == ('3'):
print ('')
print ('Type a path where you would like to save files.')
oliviahye = input()
os.chdir(oliviahye)
else:
hiimafunction()
workingDirectory = os.getcwd()
print ('')
print ('Current save location is now = ' + workingDirectory)
When this happens I get the following error:
UnboundLocalError: local variable 'workingDirectory' referenced before assignment
Although the error points specifically to the line:
print ('Current working directory where files are saved = ' + workingDirectory)
...the problem seems to be with this line within the function:
workingDirectory = os.getcwd()
If I remove this line in the function, there's no error, but of course the program doesn't then do what it's supposed to do either, which is to get the newly assigned working directory and assign it to variable workingDirectory. I can also give it a new variable as well (for instance, workingDirectory2) and it won't crash, but then that defeats the whole purpose of having the variable workingDirectory to display this data in the first place. I don't understand why this line gives no problem in the global scope but exactly the same line generates an error within the function, when the variable is already defined.
Reading up on this problem, adding the line:
global workingDirectory
into the first part of the program should help, because it should stop the program creating another variable with the same name locally, but it doesn't seem to do anything as the same error generates. Can anyone help?
Upvotes: 2
Views: 2618
Reputation: 155744
If you assign to a name anywhere in a function, then the name is local for the entire function.
So because you have the line:
workingDirectory = os.getcwd()
further down in the function, it doesn't matter if a global variable named workingDirectory
exists or not; when you try to do:
print ('Current working directory where files are saved = ' + workingDirectory)
it checks the slot in the locals reserved for that names, finds it empty, and raises the error.
If you want to use the global name exclusively (so on assignment, the global is changed), add:
global workingDirectory
to the top of your function (inside the function, but before all other code in the function), and make sure workingDirectory
is given some value globally either before this function is called (e.g. assign workingDirectory = "Uninitialized"
at top-level), or inside the function before it's used (e.g. move the assignment to workingDirectory
up before the print
s that use it).
If you want to print
the global, but then store the value without changing it, use a different name for the locally scoped version, and only read the global (you don't need to declare it explicitly global
in that case; as long as you never assign it, Python assumes it needs to look in nested, global, and built-in scopes to find it, in that order).
Upvotes: 2