谁能解释以下代码的异常。它仅在我将 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
谁能解释以下代码的异常。它仅在我将 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
您在作用域内分配给的任何变量都被视为局部变量(除非您声明它global
,或者在 python3 中nonlocal
),这意味着它不会在周围的作用域中查找。
具有相同错误的简化示例:
def a(): pass
def b(): a = a()
现在,考虑这里涉及的不同范围:
全局命名空间包含a
和b
。
该函数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 解释器创建函数对象时生成的。
这原本是一条评论。OP发现这作为一个有用的答案。因此,我将其重新发布为答案
最初,sub
是一个函数。然后,它成为函数的返回值。因此,当您说 时print sub
,python 不知道sub
您指的是哪个。
编辑:
首先你定义一个函数sub
。现在,python 知道是什么了sub
。
当您创建一个变量并尝试分配给它(例如x = 2
)时,python 会评估 右侧的东西=
并将评估的值分配为 . 左侧的东西的值=
。因此,右侧的所有内容都应该实际计算。
因此,如果您的语句是x = x+1
,那么x
最好在该行之前为其分配一个值;并且前面定义x
的必须是某种与添加兼容的类型1
。
但是假设是一个函数,并且您在其他函数中x
调用了一个变量,并尝试为其分配一个使用 function 计算的值,那么这真的开始混淆您所指的python。这确实是对这个答案的过度简化,它在解释 Python 函数中的变量范围和阴影方面做得更好x
x
x
对于使用的每个变量,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 = 3
被x
用作局部变量。由于这是代码中的不一致,Python 提出了一个引起UnboundLocalError
程序员注意的问题。
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
变量。所以它会产生问题。