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


этот вопрос уже есть ответ здесь:

  • Ошибка области видимости переменной Python 10 ответов

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

Var1 = 1
Var2 = 0
def function(): 
    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()

Как я могу это исправить? Спасибо за любую помощь!

5 100

5 ответов:

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

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)

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

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

global Var1, Var2

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

Ресурсы

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

Если вы задаете значение переменной внутри функции, 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()

мне не нравится это поведение, но так работает 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.

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

Var1 = 1
Var2 = 0

def function(): 
    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

Var1 = function()

или даже сделать локальную копию глобальных переменных и работать с ними и возвращать результаты, которые затем абонент может правильно назначить

def function():
v1, v2 = Var1, Var2
# calculate using the local variables v1 & v2
return v1 - 1

Var1 = function()