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.
This is because, even though exists, you're also using an assignment statement on the name inside of the function ( at the bottom line). Naturally, this creates a variable inside the function's scope called (truthfully, a or will only update (reassign) an existing variable, but for reasons unknown (likely consistency in this context), Python treats it as an assignment). The Python interpreter sees this at module load time and decides (correctly so) that the global scope's should not be used inside the local scope, which leads to a problem when you try to reference the variable before it is locally assigned.
Using global variables, outside of necessity, is usually frowned upon by Python developers, because it leads to confusing and problematic code. However, if you'd like to use them to accomplish what your code is implying, you can simply add:
inside the top of your function. This will tell Python that you don't intend to define a or variable inside the function's local scope. The Python interpreter sees this at module load time and decides (correctly so) to look up any references to the aforementioned variables in the global scope.
- the Python website has a great explanation for this common issue.
- Python 3 offers a related statement - check that out as well.