如何修复“UnboundLocalError:赋值前引用的局部变量”? [重复]

问题描述 投票:0回答:5

以下代码给出错误

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

我该如何解决这个问题?

python scope
5个回答
746
投票

这是因为,即使

Var1
存在,您也在函数内部的名称
Var1
上使用赋值语句(
Var1 -= 1
在底行)。当然,这会在函数作用域内创建一个名为
Var1
的变量(事实上,
-=
+=
只会更新(重新分配)现有变量,但由于未知的原因(在这种情况下可能是一致性),Python 会对待它作为作业)。 Python 解释器在模块加载时看到这一点,并决定(正确地)全局作用域的
Var1
不应在本地作用域内使用,这会在您尝试在本地分配变量之前引用该变量时导致问题。

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

global Var1, Var2

这将告诉 Python,您打算在函数的局部作用域内定义

Var1
Var2
变量。 Python 解释器在模块加载时看到这一点,并决定(正确地)在全局范围内查找对上述变量的任何引用。

一些资源

  • Python 网站对这个常见问题有很好的解释
  • Python 3 提供了相关的
    nonlocal
    语句 - 也请检查一下。

171
投票

如果您在函数内设置变量的值,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()

106
投票

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

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)

14
投票

我不喜欢这种行为,但这就是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
,因此它不再是函数了。

幸运的是,在

print
添加括号后,在 Python3 中工作正常。


6
投票

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

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()
© www.soinside.com 2019 - 2024. All rights reserved.