Python 3:UnboundLocalError:分配前引用的局部变量[重复]

Posted

技术标签:

【中文标题】Python 3:UnboundLocalError:分配前引用的局部变量[重复]【英文标题】:Python 3: UnboundLocalError: local variable referenced before assignment [duplicate] 【发布时间】:2012-06-06 18:58:48 【问题描述】:

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

我该如何解决这个问题?感谢您的帮助!

【问题讨论】:

请注意,如果您使用dic = 'Var1':1, 'Var2':0 并通过字典访问 Var1 和 Var2,它将起作用。 题外话,但是Var1 =- 1被解析为Var1 = -1,而不是Var1 -= 1 为什么没有给出错误 UnboundLocalError: local variable 'Var2' referenced before assignment?即使您将 if Var2 == 0 和 Var1 > 0: 更改为 if Var2 == 0: @chikitin 它不会为 Var2 提供错误,因为在您的函数中,您没有为 Var2 分配任何值,因此默认情况下它会考虑 Var2 的全局值。但是,既然您提到了 Var1=- 1,python 将其解释为 Var1 = -1,它认为 Var1 被分配了一个局部值,因此 Var1 成为一个局部变量和一个全局变量,python 认为它是分开的。由于 Var1 的赋值是在同一函数中使用 Var1 之后进行的,因此我们在赋值错误之前得到了这个引用。希望这能提供一些清晰 @chikitin 以防万一,如果您也想为 Var2 弹出错误以检查和澄清您的疑问,只需在 Var1=-1 语句下方为 Var2 分配一些值,然后您Var2 也会出错。 【参考方案1】:

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

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

global Var1, Var2

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

一些资源

Python 网站有一个great explanation 来解决这个常见问题。 Python 3 提供了一个相关的 nonlocal 语句 - 也请检查一下。

【讨论】:

@user7344209 确实如此。理想情况下,答案应该解释显示的实际示例中发生了什么,以及如何解决这个问题,而不是建议一种完全不同的方法。 “自然”,我觉得这不太自然。 @dumbledad 我的意思是“自然地”,因为+= 是一个赋值运算符(iadd,代表“就地添加”) 很好地解释了一个可行的解决方案 这种现象应该归咎于什么过程?我想看看其他语言是否有类似的功能,但我不确定要谷歌搜索什么。【参考方案2】:

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

【讨论】:

【参考方案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)

【讨论】:

我认为这个简单的示例代码只是说明了问题。对于这种情况,具体的解决方案还不够明确。【参考方案4】:

我不喜欢这种行为,但这就是 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中可以正常工作。

【讨论】:

【参考方案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()

【讨论】:

以上是关于Python 3:UnboundLocalError:分配前引用的局部变量[重复]的主要内容,如果未能解决你的问题,请参考以下文章

linux 系统 如何 安装 python (python 3.8)

python3-day3-python基础3

CentOS-6.9升级到Python-3.5

第二课 python解释器 2019/3/3

如何从Python 3.4 升级到 Python 3.5

CentOS 6 下安装Python 3