下面的代码给出了错误UnboundLocalError:在赋值前引用的局部变量'Var1':

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()

我该如何解决这个问题?


当前回答

我不喜欢这种行为,但这就是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)中的局部变量。你可以添加一个全局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中添加括号打印后,它可以正常工作。

其他回答

为什么不简单地返回计算值并让调用者修改全局变量呢?在函数中操作全局变量不是一个好主意,如下所示:

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()

我不喜欢这种行为,但这就是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)中的局部变量。你可以添加一个全局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中添加括号打印后,它可以正常工作。

如果你在函数中设置了一个变量的值,python会将其理解为创建了一个同名的局部变量。这个局部变量掩盖了全局变量。

在你的例子中,Var1被认为是一个局部变量,它在被设置之前就被使用了,因此出现了错误。

为了解决这个问题,你可以通过在函数中放入全局变量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()

This is because, even though Var1 exists, you're also using an assignment statement on the name Var1 inside of the function (Var1 -= 1 at the bottom line). Naturally, this creates a variable inside the function's scope called Var1 (truthfully, a -= or += will only update (reassign) an existing variable, but for reasons unknown (likely consistency in this context), Python treats it as an assignment). The Python interpreter sees this at module load time and decides (correctly so) that the global scope's Var1 should not be used inside the local scope, which leads to a problem when you try to reference the variable before it is locally assigned.

Python开发人员通常不赞成使用全局变量,因为它会导致令人困惑和有问题的代码。然而,如果你想用它们来完成你的代码所暗示的,你可以简单地在你的函数顶部添加:

global Var1, Var2

这将告诉Python,您不打算在函数的局部作用域内定义Var1或Var2变量。Python解释器在模块加载时看到这一点,并决定(正确地)在全局作用域中查找对上述变量的任何引用。

一些资源

Python网站对这个常见问题有很好的解释。 Python 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)