Sometimes you may suddenly start getting UnboundLocalError
in your code which was working perfectly just minutes ago. And what you did is just added an assignment statement.
Lets say your code is as below, which is working fine.
rana@brahma:~$ python3
Python 3.5.2 (default, Nov 12 2018, 13:43:14)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> x = 5
>>> def printx():
... print(x)
...
>>> printx()
5
>>>
Now you added an assignment statement inside printx
function where you are increasing the value of global variable x
. You will start getting UnboundLocalError
.
>>> x = 5
>>> def printx():
... print(x)
... x = 7
...
>>> printx()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in printx
UnboundLocalError: local variable 'x' referenced before assignment
>>>
What caused UnboundLocalError?
In python all the variables inside a function are global if they are not assigned any value to them. That means if a variable is only referenced inside a function, it is global. However if we assign any value to a variable inside a function, its scope becomes local to that unless explicitly declared global.
In first example, we are not assigning any value to x variable inside function and just referencing it to print. Hence x is global.
In second example, we assigned the value 7 to x, hence x's scope is local to function and we tried to print it before assigning any value to x.
Similarly, you will get UnboundLocalError in scenario similar to below example.
>>> x = 5
>>> def printx():
... x = x + 6
... print(x)
...
>>> printx()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in printx
UnboundLocalError: local variable 'x' referenced before assignment
>>>
UnboundLocalError can be solved by changing the scope of the variable which is complaining. You need to explicitly declare the variable global.
>>> x = 5
>>> def printx():
... global x
... print(x)
... x = x + 1
...
>>> printx()
5
>>>
Variable x's scope in function printx
is global. You can verify the same by printing the value of x in terminal and it will be 6.
>>> x = 5
>>> def printx():
... global x
... print(x)
... x = x + 1
...
>>> printx()
5
>>> print(x)
6
>>>
Remember that same thing can be done using nonlocal
keyword. But mind it that nonlocal binds the variable to nearest enclosing scope except global. Lets understand this with an example.
x = 15
# I know, poor choice of function names.
def func1():
x = 10
def func2():
nonlocal x
# here x refers to x with value 10
x += 1
print("func2 ", x)
# call func2
func2()
print("func1 ", x)
def func3():
global x
print("func3 ", x)
# call func3
func3()
# call func1
func1()
Output will be:
rana@brahma:others$ python3 unbound_local_error.py
func2 11
func1 11
func3 15
1. Use global keyword with a variable if only you are assigning value to that variable inside a function and you want to overwrite the value of variable declared in global scope.
2. Use nonlocal keyword in nested scopes.
Host your Django App for free (or in only $5 with custom domain name)