Python 3: UnboundLocalError:赋值前引用的本地变量

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

我该如何解决这个问题?

1113591 次浏览

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

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的变量(实际上,-=+=只会更新(重新赋值)现有变量,但由于未知原因(可能是本上下文中的一致性),Python将其视为赋值)。Python解释器在模块加载时看到这一点,并决定(正确地)全局作用域的Var1不应该在局部作用域内使用,这导致当你试图在局部赋值之前引用变量时出现问题。

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

global Var1, Var2

这将告诉Python你打算在函数的局部作用域内定义一个Var1Var2变量。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()

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

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)中的局部变量。你可以添加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()

它确实有效;也就是说,print [f for f in [1, 2, 3]]现在将全局变量f更改为3,因此它不再是一个函数。

幸运的是,在将括号添加到print后,它在Python3中工作正常。