If you try to reference a local variable before assigning a value to it within the body of a function, you will encounter the UnboundLocalError: local variable referenced before assignment.
The preferable way to solve this error is to pass parameters to your function, for example:
test_var = 0 def test_func(test_var): test_var += 1 return test_var test_func(test_var)
Alternatively, you can declare the variable as global to access it while inside a function. For example,
test_var = 0 def test_func(): global test_var test_var += 1 return test_var test_func()
This tutorial will go through the error in detail and how to solve it with code examples.
Table of contents
What is Scope in Python?
Scope refers to a variable being only available inside the region where it was created. A variable created inside a function belongs to the local scope of that function, and we can only use that variable inside that function.
A variable created in the main body of the Python code is a global variable and belongs to the global scope. Global variables are available within any scope, global and local.
UnboundLocalError: local variable referenced before assignment
UnboundLocalError occurs when we try to modify a variable defined as local before creating it. If we only need to read a variable within a function, we can do so without using the global keyword. Consider the following example that demonstrates a variable var
created with global scope and accessed from test_func
:
var = 10 def test_func(): print(var) test_func()
10
If we try to assign a value to var
within test_func
, the Python interpreter will raise the UnboundLocalError:
var = 10 def test_func(): var += 1 print(var) test_func()
--------------------------------------------------------------------------- UnboundLocalError Traceback (most recent call last) Input In [17], in <cell line: 6>() 4 var += 1 5 print(var) ----> 6 test_func() Input In [17], in test_func() 3 def test_func(): ----> 4 var += 1 5 print(var) UnboundLocalError: local variable 'var' referenced before assignment
This error occurs because when we make an assignment to a variable in a scope, that variable becomes local to that scope and overrides any variable with the same name in the global or outer scope.
var +=1
is similar to var = var + 1
, therefore the Python interpreter should first read var
, perform the addition and assign the value back to var
.
var
is a variable local to test_func
, so the variable is read or referenced before we have assigned it. As a result, the Python interpreter raises the UnboundLocalError.
Example #1: Accessing a Local Variable
Let’s look at an example where we define a global variable number. We will use the increment_func
to increase the numerical value of number
by 1.
number = 10 def increment_func(): number += 1 return number print(increment_func())
Let’s run the code to see what happens:
--------------------------------------------------------------------------- UnboundLocalError Traceback (most recent call last) Input In [19], in <cell line: 7>() 4 number += 1 5 return number ----> 7 print(increment_func()) Input In [19], in increment_func() 3 def increment_func(): ----> 4 number += 1 5 return number UnboundLocalError: local variable 'number' referenced before assignment
The error occurs because we tried to read a local variable before assigning a value to it.
Solution #1: Passing Parameters to the Function
We can solve this error by passing a parameter to increment_func
. This solution is the preferred approach. Typically Python developers avoid declaring global variables unless they are necessary. Let’s look at the revised code:
number = 10 def increment_func(number): number += 1 return number print(increment_func(number))
We have assigned a value to number
and passed it to the increment_func
, which will resolve the UnboundLocalError. Let’s run the code to see the result:
11
We successfully printed the value to the console.
Solution #2: Use Global Keyword
We also can solve this error by using the global
keyword. The global statement tells the Python interpreter that inside increment_func
, the variable number is a global variable even if we assign to it in increment_func
. Let’s look at the revised code:
number = 10 def increment_func(): global number number += 1 return number print(increment_func())
Let’s run the code to see the result:
11
We successfully printed the value to the console.
Example #2: Function with if-elif statements
Let’s look at an example where we collect a score from a player of a game to rank their level of expertise. The variable we will use is called score and the calculate_level
function takes in score
as a parameter and returns a string containing the player’s level
.
score = int(input("Enter your score between 0 and 100: ")) def calculate_level(score): if score > 90: level = 'expert' elif score > 70: level = 'advanced' elif score > 55: level = 'intermediate' return level
In the above code, we have a series of if-elif statements for assigning a string to the level
variable. Let’s run the code to see what happens:
print(f'Your level is: {calculate_level(score)}')
Enter your score between 0 and 100: 40 --------------------------------------------------------------------------- UnboundLocalError Traceback (most recent call last) Input In [12], in <cell line: 1>() ----> 1 print(f'Your level is: {calculate_level(score)}') Input In [11], in calculate_level(score) 7 elif score > 55: 8 level = 'intermediate' ----> 9 return level UnboundLocalError: local variable 'level' referenced before assignment
The error occurs because we input a score
equal to 40
. The conditional statements in the function do not account for a value below 55
, therefore when we call the calculate_level
function, Python will attempt to return level
without any value assigned to it.
Solution #1: Include else statement
We can solve this error by completing the set of conditions with an else statement. The else statement will provide an assignment to level for all scores lower than 55
. Let’s look at the revised code:
score = int(input("Enter your score between 0 and 100: ")) def calculate_level(score): if score > 90: level = 'expert' elif score > 70: level = 'advanced' elif score > 55: level = 'intermediate' else: level = 'beginner' return level
In the above code, all scores below 55
are given the beginner level. Let’s run the code to see what happens:
print(f'Your level is: {calculate_level(score)}')
Enter your score between 0 and 100: 40 Your level is: beginner
Solution #2: Use global keyword
We can also create a global variable level
and then use the global
keyword inside calculate_level
. Using the global
keyword will ensure that the variable is available in the local scope of the calculate_level
function. Let’s look at the revised code.
score = int(input("Enter your score between 0 and 100: ")) level = 'beginner' def calculate_level(score): global level if score > 90: level = 'expert' elif score > 70: level = 'advanced' elif score > 55: level = 'intermediate' return level
In the above code, we put the global statement inside the function and at the beginning. Note that the “default” value of level
is beginner
and we do not include the else
statement in the function. Let’s run the code to see the result:
print(f'Your level is: {calculate_level(score)}')
40 Your level is: beginner
Summary
Congratulations on reading to the end of this tutorial! The UnboundLocalError: local variable referenced before assignment occurs when you try to reference a local variable before assigning a value to it. Preferably, you can solve this error by passing parameters to your function. Alternatively, you can use the global keyword.
If you have if-elif statements in your code where you assign a value to a local variable and do not account for all outcomes, you may encounter this error. In which case, you must include an else statement to account for the missing outcome.
For further reading on Python code blocks and structure, go to the article: How to Solve Python IndentationError: unindent does not match any outer indentation level.
Go to the online courses page on Python to learn more about Python for data science and machine learning.
Have fun and happy researching!
Suf is a senior advisor in data science with deep expertise in Natural Language Processing, Complex Networks, and Anomaly Detection. Formerly a postdoctoral research fellow, he applied advanced physics techniques to tackle real-world, data-heavy industry challenges. Before that, he was a particle physicist at the ATLAS Experiment of the Large Hadron Collider. Now, he’s focused on bringing more fun and curiosity to the world of science and research online.