Local variable referenced before assignment python ошибка

Ситуация: вы пишете простую программу на Python, которая что-то считает по заданному алгоритму. Сначала всё идёт как обычно: объявляется глобальная переменная x, потом делаем новую функцию и обращаемся внутри неё к этой переменной:

x = 10
def sum():
x = x + 5
print(x)

Но при запуске этой функции командой sum() компьютер выдаёт ошибку:

Traceback (most recent call last):
File «main.py», line 6, in
sum()
File «main.py», line 3, in sum
x = x + 5
❌ UnboundLocalError: local variable ‘x’ referenced before assignment

Что это значит: Python ожидает, что x внутри функции будет локальной переменной. Соответственно, он ищет, где она объявляется в функции. А она не объявлена. Python падает с ошибкой.

Когда встречается: когда программист забыл про области видимости переменных или не использовал команду global.

Что делать с ошибкой UnboundLocalError: local variable referenced before assignment

Главное — определиться с областью видимости и решить, какую переменную вы хотите использовать: локальную или глобальную.

Если вам нужна локальная переменная, то её нужно добавить внутрь функции. Имя переменной при этом может совпадать с именем такой же глобальной переменной, но она никак на неё не повлияет. В этом случае нужно в функцию добавить строку x = <значение>, например:

x = 10
def sum():
    x = 11
    x = x + 5
    # выводим сумму с локальной переменной = 16
    print(x)
    
sum()
# выводим значение глобальной переменной
# оно не поменялось и равно 10
print(x)

Если мы хотим внутри функции работать с глобальной переменной, то её также нужно добавить в функцию командой global. После этого всё, что мы сделаем внутри функции с этой переменной, будет влиять и на значение глобальной переменной. Работает это так:

x = 10
def sum():
    global x
    x = x + 5
    # выводим сумму с глобальной переменной = 15
    print(x)
    
sum()
# выводим значение глобальной переменной
# оно поменялось и равно 15
print(x)

I don’t like this behavior, but this is how Python works. The question has already been answered by others, but for completeness, let me point out that Python 2 has more such quirks.

def f(x):
    return x

def main():
    print f(3)
    if (True):
        print [f for f in [1, 2, 3]]

main()

Python 2.7.6 returns an error:

Traceback (most recent call last):
  File "weird.py", line 9, in <module>
    main()
  File "weird.py", line 5, in main
    print f(3)
UnboundLocalError: local variable 'f' referenced before assignment

Python sees the f is used as a local variable in [f for f in [1, 2, 3]], and decides that it is also a local variable in f(3). You could add a global f statement:

def f(x):
    return x

def main():
    global f
    print f(3)
    if (True):
        print [f for f in [1, 2, 3]]

main()

It does work; however, f becomes 3 at the end… That is, print [f for f in [1, 2, 3]] now changes the global variable f to 3, so it is not a function any more.

Fortunately, it works fine in Python3 after adding the parentheses to print.

Python treats variables referenced only inside a function as global variables. Any variable assigned to a function’s body is assumed to be a local variable unless explicitly declared as global.

Why Does This Error Occur?

Unboundlocalerror: local variable referenced before assignment occurs when a variable is used before its created. Python does not have the concept of variable declarations. Hence it searches for the variable whenever used. When not found, it throws the error.

Before we hop into the solutions, let’s have a look at what is the global and local variables.

Local Variable Declarations vs. Global Variable Declarations

Local Variables Global Variables
A local variable is declared primarily within a Python function. Global variables are in the global scope, outside a function.
A local variable is created when the function is called and destroyed when the execution is finished. A Global Variable is created upon execution and exists in memory till the program stops.
Local Variables can only be accessed within their own function. All functions of the program can access global variables.
Local variables are immune to changes in the global scope. Thereby being more secure. Global Variables are less safer from manipulation as they are accessible in the global scope.

[Fixed] SSL module in Python is Not Available

Local Variable Referenced Before Assignment Error with Explanation

Try these examples yourself using our Online Compiler.

Let’s look at the following function:

# Variable declaration outside function (global scope)
myVar = 10


def myFunction():
      if myVar == 5:
            print("5")
      elif myVar == 10:
            print("10")
      elif myVar >= 15:
            print("greater than 15 ")
     # reassigning myVar in the function
      myVar = 0

myFunction()

Output

Local Variable Referenced Before Assignment Error

Explanation

The variable myVar has been assigned a value twice. Once before the declaration of myFunction and within myFunction itself.

Solutions

Using Global Variables

Passing the variable as global allows the function to recognize the variable outside the function.

myVar = 10
def myFunction():
     # Telling the function to consider myVar as global
      global myVar
      if myVar == 5:
            print("5")
      elif myVar == 10:
            print("10")
      elif myVar >= 15:
            print("greater than 15 ")
      myVar = 0

myFunction()

Output

10

Create Functions that Take in Parameters

Instead of initializing myVar as a global or local variable, it can be passed to the function as a parameter. This removes the need to create a variable in memory.

# Passing myVar as a parameter in the function
def myFunction(myVar):
      if myVar == 5:
            print("5")
      elif myVar == 10:
            print("10")
      elif myVar >= 15:
            print("greater than 15 ")
      myVar = 0

myFunction(10)

Output

10

UnboundLocalError: local variable ‘DISTRO_NAME’

This error may occur when trying to launch the Anaconda Navigator in Linux Systems.

Upon launching Anaconda Navigator, the opening screen freezes and doesn’t proceed to load.

$ anaconda-navigator          
Traceback (most recent call last):
  File "/home/user/anaconda3/lib/python3.7/site-packages/anaconda_navigator/widgets/main_window.py", line 541, in setup
    self.post_setup(conda_data=conda_data)
...
...
UnboundLocalError: local variable 'DISTRO_NAME' referenced before assignment

Solution 1

Try and update your Anaconda Navigator with the following command.

conda update anaconda-navigator

Solution 2

If solution one doesn’t work, you have to edit a file located at

.../anaconda3//lib/python3.7/site-packages/anaconda_navigator/api/external_apps/vscode.py

After finding and opening the Python file, make the following changes:

In the function on line 159, simply add the line:

DISTRO_NAME = None

Save the file and re-launch Anaconda Navigator.

The program takes information from a form filled out by a user. Accordingly, an email is sent using the information.

from django import forms


# Creating a Class for django forms
class MyForm(forms.Form):
    name = forms.CharField(required=True)
    email = forms.EmailField(required=True)
    msg = forms.CharField(
        required=True,
        widget=forms.Textarea
    )


...
# Create a function to retrieve info from the form
def GetContact(request):
    form_class = ContactForm
    if request.method == 'POST':
        form = form_class(request.POST)

        # Upon verifying validity, get following info and email with said info
        if form.is_valid():
            name = request.POST.get('name')
            email = request.POST.get('email')
            msg = request.POST.get('msg')

            send_mail('Subject here', msg, email, ['[email protected]'], fail_silently=False)
            return HttpResponseRedirect('blog/inicio')
            return render(request, 'blog/inicio.html', {'form': form})
...

Upon running you get the following error:

local variable 'form' referenced before assignment

Explanation

We have created a class myForm that creates instances of Django forms. It extracts the user’s name, email, and message to be sent.

A function GetContact is created to use the information from the Django form and produce an email. It takes one request parameter. Prior to sending the email, the function verifies the validity of the form. Upon True, .get() function is passed to fetch the name, email, and message. Finally, the email sent via the send_mail function

Why does the error occur?

We are initializing form under the if request.method == “POST” condition statement. Using the GET request, our variable form doesn’t get defined.

Local variable Referenced before assignment but it is global

This is a common error that happens when we don’t provide a value to a variable and reference it. This can happen with local variables. Global variables can’t be assigned.

This error message is raised when a variable is referenced before it has been assigned a value within the local scope of a function, even though it is a global variable.

Here’s an example to help illustrate the problem:

x = 10
def my_func():
    print(x)
    x += 1
my_func()

In this example, x is a global variable that is defined outside of the function my_func(). However, when we try to print the value of x inside the function, we get a UnboundLocalError with the message “local variable ‘x’ referenced before assignment”.

This is because the += operator implicitly creates a local variable within the function’s scope, which shadows the global variable of the same name. Since we’re trying to access the value of x before it’s been assigned a value within the local scope, the interpreter raises an error.

To fix this, you can use the global keyword to explicitly refer to the global variable within the function’s scope:

x = 10
def my_func():
    global x
    print(x)
    x += 1
my_func()

However, in the above example, the global keyword tells Python that we want to modify the value of the global variable x, rather than creating a new local variable. This allows us to access and modify the global variable within the function’s scope, without causing any errors.

Local variable ‘version’ referenced before assignment ubuntu-drivers

This error occurs with Ubuntu version drivers. To solve this error, you can re-specify the version information and give a split as 2 –

version = int(p_name.split('-')[-2])

Here, p_name means package name.

FAQs

How would you avoid using a global variable in multi-threads?

With the help of the threading module, you can avoid using global variables in multi-threading. Make sure you lock and release your threads correctly to avoid the race condition.

What is UnboundLocalError?

When a variable that is created locally is called before assigning, it results in Unbound Local Error in Python. The interpreter can’t track the variable.

Conclusion

Therefore, we have examined the local variable referenced before the assignment Exception in Python. The differences between a local and global variable declaration have been explained, and multiple solutions regarding the issue have been provided.

Trending Python Articles

  • [Fixed] SSL module in Python is Not Available

    [Fixed] SSL module in Python is Not Available

    May 30, 2023

  • Mastering Python Translate: A Beginner’s Guide

    Mastering Python Translate: A Beginner’s Guide

    by Namrata GulatiMay 30, 2023

  • Efficiently Organize Your Data with Python Trie

    Efficiently Organize Your Data with Python Trie

    by Namrata GulatiMay 2, 2023

  • [Fixed] modulenotfounderror: no module named ‘_bz2

    [Fixed] modulenotfounderror: no module named ‘_bz2

    by Namrata GulatiMay 2, 2023

Toggle table of contents sidebar

Распространенные проблемы/нюансы работы с функциями#

Список/словарь в который собираются данные в функции, создан за пределами функции#

Очень часто в решении заданий встречается такой нюанс: функция должна собрать какие-то данные в список/словарь
и список создан вне функции. Тогда вроде как функция работает правильно,
но при этом тест не проходит. Это происходит потому что в таком варианте функция
работает неправильно и каждый вызов добавляет элементы в тот же список:

In [1]: result = []

In [2]: def func(items):
   ...:     for i in items:
   ...:         result.append(i*100)
   ...:     return result
   ...:

In [3]: func([1, 2, 3])
Out[3]: [100, 200, 300]

In [4]: func([7, 8])
Out[4]: [100, 200, 300, 700, 800]

Исправить это можно переносом строки создания списка в функцию:

In [20]: def func(items):
    ...:     result = []
    ...:     for i in items:
    ...:         result.append(i*100)
    ...:     return result
    ...:

In [21]: func([1, 2, 3])
Out[21]: [100, 200, 300]

In [22]: func([7, 8])
Out[22]: [700, 800]

Всё, что относится к функции лучше всегда писать внутри функции.
Тест тут не проходит потому что внутри файла задания функция вызывается первый
раз — всё правильно, а потом тест вызывает её второй раз и там вдруг в два раза больше данных чем нужно.

Значения по умолчанию в параметрах создаются во время создания функции#

Пример функции, которая должна выводить текущую дату и время при каждом вызове:

In [1]: from datetime import datetime

In [2]: import time

In [3]: def print_current_datetime(ptime=datetime.now()):
   ...:     print(f">>> {ptime}")
   ...:

In [4]: for i in range(3):
   ...:     print("Имитируем долгое выполнение...")
   ...:     time.sleep(1)
   ...:     print_current_datetime()
   ...:
Имитируем долгое выполнение...
>>> 2021-02-23 09:01:49.845425
Имитируем долгое выполнение...
>>> 2021-02-23 09:01:49.845425
Имитируем долгое выполнение...
>>> 2021-02-23 09:01:49.845425

Так как datetime.now() указано в значении по умолчанию,
это значение создается во время создания функции и в итоге при каждом вызове
время одно и то же. Для корректного вывода, надо вызывать datetime.now()
в теле функции:

In [5]: def print_current_datetime():
   ...:     print(f">>> {datetime.now()}")
   ...:

Второй пример где этот нюанс может привести к неожиданным результатам,
если о нем не знать — изменяемые типы данных в значении по умолчанию.

Например, использование списка в значении по умолчанию:

In [15]: def add_item(item, data=[]):
    ...:     data.append(item)
    ...:     return data
    ...:

В этом случае список data создается один раз — при создании функции и
при вызове функции, данные добавляются в один и тот же список.
В итоге все повторные вызовы будут добавлять элементы:

In [16]: add_item(1)
Out[16]: [1]

In [17]: add_item(2)
Out[17]: [1, 2]

In [18]: add_item(4)
Out[18]: [1, 2, 4]

Если нужно сделать так, чтобы параметр data был необязательным и по умолчанию
создавался пустой список, надо сделать так:

In [22]: def add_item(item, data=None):
    ...:     if data is None:
    ...:         data = []
    ...:     data.append(item)
    ...:     return data
    ...:

In [23]: add_item(1)
Out[23]: [1]

In [24]: add_item(2)
Out[24]: [2]

Ошибка UnboundLocalError: local variable referenced before assignment#

Ошибка может возникнуть в таких случаях:

  • обращение к переменной в функции идет до ее создания — это может быть
    случайность (ошибка) или следствие того, что какое-то условие не выполнилось

  • обращение внутри функции к глобальной переменной, но при этом внутри функции
    создана такая же переменная позже

Первый случай — обратились к переменной до ее создания:

def f():
    print(b)
    b = 55

In [6]: f()
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
Input In [6], in <cell line: 1>()
----> 1 f()

Input In [5], in f()
      1 def f():
----> 2     print(b)
      3     b = 55

UnboundLocalError: local variable 'b' referenced before assignment

Переменная создается в условии, а условие не выполнилось:

def f():
    if 5 > 8:
        b = 55
    print(b)

In [8]: f()
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
Input In [8], in <cell line: 1>()
----> 1 f()

Input In [7], in f()
      2 if 5 > 8:
      3     b = 55
----> 4 print(b)

UnboundLocalError: local variable 'b' referenced before assignment

Имя глобальной и локальной переменной одинаковое и внутри функции сначала идет
попытка обращения к глобальной, потом создание локальной:

a = 10

def f():
    print(a)
    a = 55
    print(a)


In [4]: f()
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
Input In [4], in <cell line: 1>()
----> 1 f()

Input In [3], in f()
      1 def f():
----> 2     print(a)
      3     a = 55
      4     print(a)

UnboundLocalError: local variable 'a' referenced before assignment

Python должен определить область видимости переменной. И в случае функций, Python
считает, что переменная локальная, если она создана внутри функции.
На момент когда мы доходим до вызова функции, Python уже решил, что a это
локальная переменная и именно из-за этого первая строка print(a) дает ошибку.

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?
  • UnboundLocalError: local variable referenced before assignment
  • Example #1: Accessing a Local Variable
    • Solution #1: Passing Parameters to the Function
    • Solution #2: Use Global Keyword
  • Example #2: Function with if-elif statements
    • Solution #1: Include else statement
    • Solution #2: Use global keyword
  • Summary

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!

Понравилась статья? Поделить с друзьями:
  • Linux ошибка permission denied
  • Linux как посмотреть ошибки на интерфейсе
  • Linux журнал ошибок системы
  • Linux xampp 403 ошибка
  • Linux ubuntu проверка диска на ошибки