How To Solve “UnboundLocalError: local variable referenced before assignment” In Python

The “UnboundLocalError: local variable referenced before assignment” is bound to happen if you haven’t mastered names and scopes in Python. Check out the explanation below to know how you can fix this issue.

UnboundLocalError: local variable referenced before assignment

Reproduce The Error

Below is a common mistake many newcomers make when they access and modify variables within a function in Python:

s = 'Tutopal'
def test():
    s += '.net'
    print(s)
test()

While they might expect the snippet would print out ‘Tutopal.net’, the Python runtime returns this error instead:

File "/home/Tutopal/python.py", line 5, in <module>
    test()
  File "/home/itturiapython.py", line 3, in test
    s += '.net'
UnboundLocalError: local variable 's' referenced before assignment

 This is weird considering the following code, which behaves normally in Python:

s = 'Tutopal'
def test():
    print(s)
test()

Output:

Tutopal

Why does the first program result in an error while the second doesn’t? Why can we invoke the print() function over it but the += operator would throw the UnboundLocalError exception.

To know why this error happens and how to solve it, you will need a good understanding of how scopes work in Python.

Names And Scopes In Python

Like other programming languages, Python defines and uses different scopes so names (like variables, objects, functions, and so on) can be referenced or accessed. It is one of the most important concepts in programming and varies between languages.

Python has three types of namespaces, which are collections of names: function, module, and built-in. They map names to objects, and you will need to access those namespaces when referencing a specific name.

Namespaces are created at different times and possess different timelines. The built-name namespace contains built-in functions like print() and exception names and is created when you start up the interpreter. This namespace continues to exist for the whole timeline of the Python interpreter and never gets deleted.

A module has its own namespace, which holds every name defined in it. It is created when you load it. Likewise, local names belong to a function namespace, which is created when that function is invoked.

Scopes define which code region in Python can access which namespace. When your code references a name, Python will use these definitions to search for that name.

It begins with the local names in the innermost scope, then the namespaces of enclosing functions, the current module, and the built-in names.

That is why, in the first example, the program can print out the string successfully. The print() function needs to access the s variable. Python can’t find this name in the innermost scope, which are names defined in the test() function. However, the s variable is located in the enclosing module. It is therefore accessible to the print() function.

This isn’t the case with the second example, which involves an assignment operation due to a well-known quirk of Python. By default, assignments always apply to the innermost scope. Remember that assignments in Python are only references to real objects, meaning they don’t copy data.

When you invoke the s+=’.net’ statement, Python will look for the s name in the test()’s namespace. As there is none, it will throw the UnboundLocalError error. Python raises this exception when you make a reference to a local variable within a method or function, but the interpreter can’t find any bound to that name.

How To Solve The Error

You will need to use the global statement within the test() function to get rid of this error. It affects the whole code block of the function and tells it to interpret certain names as global.

s = 'Tutopal'
def test():
    global s
    s += '.net'
    print(s)
test()

Output:

Tutopal.com

As the s variable has been treated as a global variable, the assignment operator looks for it in the global scope.

Summary

The “UnboundLocalError: local variable referenced before assignment” error occurs when your assignments use a variable that doesn’t live in the innermost scope. The global statement can tell the Python interpreter to search for in the global scope, helping solve the issue.

If you want to go further and use these namespaces to define static variables in Python, this guide will show you how.

Reference Sources:

https://stackoverflow.com/questions/10851906/python-3-unboundlocalerror-local-variable-referenced-before-assignment

https://www.programiz.com/python-programming/namespace

https://docs.python.org/3/tutorial/classes.html

Leave a Reply

Your email address will not be published. Required fields are marked *