Local variable referenced before assignment in Python

avatar
Borislav Hadzhiev

Last updated: Apr 8, 2024
4 min

banner

# Local variable referenced before assignment in Python

The Python "UnboundLocalError: Local variable referenced before assignment" occurs when we reference a local variable before assigning a value to it in a function.

To solve the error, mark the variable as global in the function definition, e.g. global my_var.

unboundlocalerror local variable name referenced before assignment

Here is an example of how the error occurs.

main.py
name = 'Alice' def example(): # โ›”๏ธ UnboundLocalError: local variable 'name' referenced before assignment print(name) name = 'Bob' # ๐Ÿ‘ˆ๏ธ This makes the variable local example()

We assign a value to the name variable in the function.

This makes the name variable local to the function and the local name variable shadows the one in the global scope.

# Mark the variable as global to solve the error

To solve the error, mark the variable as global in your function definition.

main.py
name = 'Alice' def example(): # ๐Ÿ‘‡๏ธ Mark global global name print(name) name = 'Bob' example() # ๐Ÿ‘‰๏ธ 'Alice' example() # ๐Ÿ‘‰๏ธ 'Bob'

mark variable as global

If a variable is assigned a value in a function's body, it is a local variable unless explicitly declared as global.

# Local variables shadow global ones with the same name

You could reference the global name variable from inside the function but if you assign a value to the variable in the function's body, the local variable shadows the global one.

main.py
name = 'Alice' def example(): # โœ… This is ok print(name) example() # ๐Ÿ‘‰๏ธ 'Alice'

accessing global variables in functions

Accessing the name variable in the function is perfectly fine.

On the other hand, variables declared in a function cannot be accessed from the global scope.

main.py
def example(): name = 'Bobby Hadz' example() # โ›”๏ธ Error print(name)

variables declared in function cannot be accessed in global scope

The name variable is declared in the function, so trying to access it from outside causes an error.

Make sure you don't try to access the variable before using the global keyword, otherwise, you'd get the SyntaxError: name 'X' is used prior to global declaration error.

# Returning a value from the function instead

An alternative solution to using the global keyword is to return a value from the function and use the value to reassign the global variable.

main.py
name = 'Alice' def example(): print(name) # ๐Ÿ‘‰๏ธ 'Alice' new_name = 'Bob' return new_name result = example() print(result) # ๐Ÿ‘‰๏ธ 'Bob' name = result print(name) # ๐Ÿ‘‰๏ธ 'Bob'

return value from the function

We simply return the value that we eventually use to assign to the name global variable.

# Passing the global variable as an argument to the function

You should also consider passing the global variable as an argument to the function.

main.py
name = 'Alice' def example(first): full_name = first + ' Smith' return full_name result = example(name) print(result) # ๐Ÿ‘‰๏ธ 'Alice Smith'

pass global variable as argument to function

We passed the name global variable as an argument to the function.

When we assign a value to a variable in a scope, that variable becomes local to that scope and shadows variables with the same name in the outer scope.

If we assign a value to a variable in a function, the variable is assumed to be local unless explicitly declared as global.

# Assigning a value to a local variable from an outer scope

If you have a nested function and are trying to assign a value to the local variables from the outer function, use the nonlocal keyword.

main.py
def outer(): # ๐Ÿ‘‡๏ธ Initialize message variable message = '' def inner(): # ๐Ÿ‘‡๏ธ Mark the message variable as nonlocal nonlocal message message = 'hello world' print(message) inner() print(message) # ๐Ÿ‘‰๏ธ "hello world" outer()

assign value to local variable from outer scope

The nonlocal keyword allows us to work with the local variables of enclosing functions.

Note that we had to initialize the message variable in the outer function, but we were able to change its value in the inner function.

Had we not used the nonlocal statement, the call to the print() function would have returned an empty string.

main.py
def outer(): # ๐Ÿ‘‡๏ธ Initialize message variable message = '' def inner(): # ๐Ÿ‘‡๏ธ Declares message in inner's scope message = 'hello world' print(message) inner() print(repr(message)) # ๐Ÿ‘‰๏ธ "" outer()

not using nonlocal prints empty string

Printing the message variable on the last line of the function shows an empty string because the inner() function has its own scope.

Changing the value of the variable in the inner scope is not possible unless we use the nonlocal keyword.

Instead, the message variable in the inner function simply shadows the variable with the same name from the outer scope.

# Discussion

As shown in this section of the documentation, when you assign a value to a variable inside a function, the variable:

  1. Becomes local to the scope.
  2. Shadows any variables from the outer scope that have the same name.

The last line in the example function assigns a value to the name variable, marking it as a local variable and shadowing the name variable from the outer scope.

main.py
name = 'Alice' def example(): # โ›”๏ธ UnboundLocalError: local variable 'name' referenced before assignment print(name) name = 'Bob' # ๐Ÿ‘ˆ๏ธ This makes the variable local example()

At the time the print(name) line runs, the name variable is not yet initialized, which causes the error.

The most intuitive way to solve the error is to use the global keyword.

main.py
name = 'Alice' def example(): # ๐Ÿ‘‡๏ธ Mark as global global name print(name) name = 'Bob' example() # ๐Ÿ‘‰๏ธ 'Alice' example() # ๐Ÿ‘‰๏ธ 'Bob'

The global keyword is used to indicate to Python that we are actually modifying the value of the name variable from the outer scope.

  1. If a variable is only referenced inside a function, it is implicitly global.
  2. If a variable is assigned a value inside a function's body, it is assumed to be local, unless explicitly marked as global.

If you want to read more about why this error occurs, check out [this section](this section) of the docs.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev