Select Page

Python UnboundLocalError: local variable referenced before assignment

by | Programming, Python, Tips

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.


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!