Вопрос-Ответ

Python 3: UnboundLocalError: local variable referenced before assignment [duplicate]

Python 3: UnboundLocalError: локальная переменная, на которую ссылаются перед назначением

Следующий код выдает ошибку UnboundLocalError: local variable 'Var1' referenced before assignment:

Var1 = 1
Var2 = 0
def function():
if Var2 == 0 and Var1 > 0:
print("Result 1")
elif Var2 == 1 and Var1 > 0:
print("Result 2")
elif Var1 < 1:
print("Result 3")
Var1 -= 1
function()

Как я могу это исправить?

Переведено автоматически
Ответ 1

Это потому, что, несмотря на то, что Var1 существует, вы также используете оператор присваивания имени Var1 внутри функции (Var1 -= 1 в нижней строке). Естественно, это создает переменную внутри области видимости функции с именем Var1 (по правде говоря, -= или += обновит (переназначит) только существующую переменную, но по неизвестным причинам (вероятно, согласованность в данном контексте) Python рассматривает это как присваивание). Интерпретатор Python видит это во время загрузки модуля и решает (правильно), что глобальная область Var1 не должна использоваться внутри локальной области, что приводит к проблеме при попытке сослаться на переменную до того, как она будет назначена локально.

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

global Var1, Var2

Это сообщит Python, что вы не собираетесь определять переменную Var1 or Var2 внутри локальной области видимости функции. Интерпретатор Python видит это во время загрузки модуля и решает (правильно) поискать любые ссылки на вышеупомянутые переменные в глобальной области видимости.

Некоторые ресурсы


  • на веб-сайте Python есть отличное объяснение этой распространенной проблемы.

  • Python 3 предлагает связанный оператор nonlocal - проверьте и это.

Ответ 2

Если вы задаете значение переменной внутри функции, python понимает это как создание локальной переменной с таким именем. Эта локальная переменная маскирует глобальную переменную.

В вашем случае, Var1 рассматривается как локальная переменная, и она используется перед установкой, отсюда ошибка.

Чтобы решить эту проблему, вы можете явно указать, что это глобальная переменная, поместив global Var1 в свою функцию.

Var1 = 1
Var2 = 0
def function():
global Var1
if Var2 == 0 and Var1 > 0:
print("Result One")
elif Var2 == 1 and Var1 > 0:
print("Result Two")
elif Var1 < 1:
print("Result Three")
Var1 =- 1
function()
Ответ 3

Вы можете исправить это, передавая параметры, а не полагаясь на глобальные значения

def function(Var1, Var2): 
if Var2 == 0 and Var1 > 0:
print("Result One")
elif Var2 == 1 and Var1 > 0:
print("Result Two")
elif Var1 < 1:
print("Result Three")
return Var1 -= 1
function(1, 1)
Ответ 4

Мне не нравится такое поведение, но именно так работает Python. На этот вопрос уже отвечали другие, но для полноты картины позвольте мне указать, что в Python 2 таких особенностей больше.

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 возвращает ошибку:

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 видит, что f используется как локальная переменная в [f for f in [1, 2, 3]], и решает, что это также локальная переменная в f(3). Вы могли бы добавить global f оператор:

def f(x):
return x

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

main()

Это действительно работает; однако в конце f становится 3 ... То есть, print [f for f in [1, 2, 3]] теперь глобальная переменная изменяется f на 3, так что это больше не функция.

К счастью, это отлично работает в Python3 после добавления круглых скобок в print.

python python-3.x