299

以下代码给出了错误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()

我怎样才能解决这个问题?

4

5 回答 5

616

这是因为,即使Var1存在,您也在Var1函数内部的名称上使用了赋值语句(Var1 -= 1在底线)。自然,这会在函数的范围内创建一个变量,称为Var1(实际上,a -=or+=只会更新(重新分配)现有变量,但由于未知原因(可能在此上下文中保持一致性),Python 将其视为赋值)。Python 解释器在模块加载时看到这一点,并决定(正确地)全局范围Var1不应该在本地范围内使用,当您尝试在本地分配之前引用变量时会导致问题。

Python 开发人员通常不赞成在不必要的情况下使用全局变量,因为它会导致代码混乱和有问题。但是,如果您想使用它们来完成您的代码所暗示的内容,您可以简单地在函数顶部添加:

global Var1, Var2

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

一些资源

  • Python 网站对这个常见问题有很好的解释
  • Python 3 提供了一个相关的nonlocal声明——也检查一下。
于 2012-06-01T14:19:51.503 回答
131

如果您在函数内部设置变量的值,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()
于 2012-06-01T14:19:54.873 回答
98

您可以通过传递参数而不是依赖全局来解决此问题

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)
于 2012-06-01T14:15:32.050 回答
12

我不喜欢这种行为,但这就是 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]]现在将全局变量更改f3,因此它不再是函数。

幸运的是,在将括号添加到print.

于 2014-10-27T01:10:52.470 回答
5

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

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()
于 2014-02-17T18:39:37.837 回答