1

谁能解释以下代码的异常。它仅在我将 display() 中的 var sub 更改为另一个名称时才有效。也没有全局变量 sub 。所以发生了什么事 ?

def sub(a, b):
    return a - b

def display():
    sub = sub(2,1) // if change to sub1 or sth different to sub, it works
    print sub
4

4 回答 4

2

您在作用域内分配给的任何变量都被视为局部变量(除非您声明它global,或者在 python3 中nonlocal),这意味着它不会在周围的作用域中查找。

具有相同错误的简化示例:

def a(): pass

def b(): a = a()

现在,考虑这里涉及的不同范围:

全局命名空间包含ab

该函数a不包含局部变量。

该函数b包含一个赋值a- 这意味着它被解释为一个局部变量并a从外部范围(在本例中为全局范围)隐藏该函数。由于在调用之前a没有在内部定义b,它是一个未绑定的局部变量,因此是 UnboundLocalError。这和你写这个完全一样:

def b(): x = x()

解决方法很简单:为sub调用结果选择一个不同的名称。

重要的是要注意使用和分配的顺序没有区别 - 如果你这样编写函数,错误仍然会发生:

def display():
    value = sub(2,1)         #UnboundLocalError here...
    print value
    sub = "someOtherValue"   #because you assign a variable named `sub` here

这是因为局部变量列表是在 python 解释器创建函数对象时生成的。

于 2012-10-01T12:51:47.110 回答
1

这原本是一条评论。OP发现这作为一个有用的答案。因此,我将其重新发布为答案

最初,sub是一个函数。然后,它成为函数的返回值。因此,当您说 时print sub,python 不知道sub您指的是哪个。

编辑

首先你定义一个函数sub。现在,python 知道是什么了sub

当您创建一个变量并尝试分配给它(例如x = 2)时,python 会评估 右侧的东西=并将评估的值分配为 . 左侧的东西的值=。因此,右侧的所有内容都应该实际计算。

因此,如果您的语句是x = x+1,那么x最好在该行之前为其分配一个值;并且前面定义x的必须是某种与添加兼容的类型1

但是假设是一个函数,并且您在其他函数中x调用了一个变量,并尝试为其分配一个使用 function 计算的值,那么这真的开始混淆您所指的python。这确实是对这个答案的过度简化,它在解释 Python 函数中的变量范围和阴影方面做得更好xxx

于 2012-10-01T12:26:58.633 回答
1

对于使用的每个变量,Python 都会确定它是局部变量还是非局部变量。引用未知变量将其标记为非本地变量。稍后重用与局部变量相同的名称被认为是程序员的错误。

考虑这个例子:

def err():
    print x # this line references x
    x = 3   # this line creates a local variable x
err()

这给你

Traceback (most recent call last):
  File "asd.py", line 5, in <module>
    err()
  File "asd.py", line 2, in err
    print x # this line references x
UnboundLocalError: local variable 'x' referenced before assignment

基本上,Python 会跟踪代码中对名称的所有引用。当它读取这一行时print x,Python 知道这x是来自外部范围(上值或全局)的变量。但是,inx = 3x用作局部变量。由于这是代码中的不一致,Python 提出了一个引起UnboundLocalError程序员注意的问题。

于 2012-10-01T13:23:48.450 回答
-1

Python 开始执行你的代码并首先获取函数

def sub(a, b):
    return a - b

所以在执行这个解释器之后得到sub一个函数。现在当来到下一行时,它发现

def display():
    sub = sub(2,1) // if change to sub1 or sth different to sub, it works
    print sub

所以第一行sub = sub (2, 1)会将sub函数转换为sub变量。从这个函数中,您将返回sub变量。所以它会产生问题。

于 2012-10-01T12:41:43.853 回答