UnboundLocalError: local variable referenced before assignment
So that sucks
Howdya fix that?
I’ll tell you. First, a simple example of the problem:
#This is valid python 2.5 code #My global variable: USER_COUNT = 0 #functions: def Main(): AddUser() def AddUser(): print 'There are',USER_COUNT,'users so far' # actually run Main() Main()
^ That program WORKS FINE. Function AddUser() just references the USER_COUNT variable, which was declared as a global (outside of any of the function blocks).
Here’s where it goes wrong: when we try to write to or we try to update the value of the global variable
#USER_COUNT is a GLOBAL variable USER_COUNT = 0 def Main(): AddUser() def AddUser(): USER_COUNT = USER_COUNT + 1 print 'There are',USER_COUNT,'users so far' Main()
Then we get: UnboundLocalError: local variable ‘USER_COUNT’ referenced before assignment
So that sucks.
The reason this happens is because AS SOON AS YOU WRITE TO A VARIABLE, that variable is AUTOMATICALLY considered LOCAL to the function block in which its declared. Namely:
#USER_COUNT is a GLOBAL! USER_COUNT = 0 def AddUser(): USER_COUNT = USER_COUNT + 1 print 'There are',USER_COUNT,'users so far'
EVEN THOUGH we declared USER_COUNT as a GLOBAL, the simple act of WRITING TO IT __ANYWHERE__ in the function scuzzles-up the “globalness” of the USER_COUNT variable, and like, automatically makes ANY use of USER_COUNT refer to a LOCAL VARIABLE inside of AddUser().
So howdya fix it?
Easy! You do this:
#global USER_COUNT = 0 def Main(): AddUser() def AddUser(): global USER_COUNT ######!!! IMPORTANT !!! Make sure # to use the GLOBAL version of USER_COUNT, not some # locally defined copy of that. I think this # might be a python feature to stop functions from # clobbering the global variables in a program USER_COUNT = USER_COUNT + 1 print 'There are',USER_COUNT,'users so far' Main()
This is an ok-nice feature that might stop a program’s functions from clobbering the globals (since you really have this “just use it” attitude to a variable and you may have no clue that you’re clobbering a global), but really it might be nice if python were more consistent and required use of this global thing for BOTH read/write. Though I guess it could be kinda convenient behavior .. I don’t know yet, haven’t programmed in python for long enough.
4 Comments
Addendum: Looks like I am not the only person who this surprises.
This was a very helpful explanation for the precise problem I was having. Thanks!
This solved my problem. Thanks!
Thank you so much for posting this!! Exactly the issue I was facing; now on to the next one! :)