Python 3:UnboundLocalError:赋值前引用的局部变量

Ede*_*row 174 python function python-3.x

以下代码给出了错误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()
Run Code Online (Sandbox Code Playgroud)

我怎样才能解决这个问题?谢谢你的帮助!

oro*_*aki 407

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

Python开发人员通常不赞成使用全局变量,因为它会导致令人困惑和有问题的代码.但是,如果您想使用它们来完成代码所暗示的内容,您只需添加:

global Var1, Var2
Run Code Online (Sandbox Code Playgroud)

在你的功能顶部.这将告诉Python您不打算在函数的本地范围内定义Var1Var2变量.Python解释器在模块加载时看到这一点并决定(正确地)以查找对全局范围中的上述变量的任何引用.

一些资源

  • Python网站对这个常见问题有很好的解释.
  • Python 3提供了一个相关的nonlocal声明 - 也可以检查一下.

  • 这应该是公认的答案,不仅给出了解决方案,还解释了导致错误的原因 (23认同)
  • “自然”,对我来说似乎并不自然。 (7认同)
  • @ user7344209 确实如此。理想情况下,答案应该解释显示的实际示例中发生的情况,以及如何解决该问题,而不是建议采用完全不同的方法。 (6认同)
  • 用可行的解决方案很好地解释了 (5认同)

mad*_*jar 77

如果在函数内部设置变量的值,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()
Run Code Online (Sandbox Code Playgroud)


Jak*_*yer 47

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

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)
Run Code Online (Sandbox Code Playgroud)

  • 我认为这个简单的示例代码仅显示了问题。对于这种情况,具体的解决方案还不够清楚。 (3认同)

osa*_*osa 9

我不喜欢这种行为,但这就是Python的工作方式.其他人已经回答了这个问题,但为了完整起见,我要指出Python 2有更多这样的怪癖.

def f(x):
    return x

def main():
    print f(3)
    if (True):
        print [f for f in [1, 2, 3]]

main()
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)

它确实有效; 然而,f在结尾变为3 ......也就是说,print [f for f in [1, 2, 3]]现在将全局变量更改f3,所以它不再是一个函数.

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


小智 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()
Run Code Online (Sandbox Code Playgroud)

甚至制作全局变量的本地副本并使用它们并返回调用者可以适当分配的结果

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

Var1 = function()
Run Code Online (Sandbox Code Playgroud)