Что означает ошибка UnboundLocalError: local variable referenced before assignment

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

x = 10

def sum():

    x = x + 5

    print(x)

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

Traceback (most recent call last):

  File "main.py", line 6, in <module>

    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)

Текст:

Миха­ил Полянин

Редак­ту­ра:

Мак­сим Ильяхов

Худож­ник:

Даня Бер­ков­ский

Кор­рек­тор:

Ири­на Михеева

Вёрст­ка:

Мария Дро­но­ва

Соц­се­ти:

Олег Веш­кур­цев