如题,现在只考虑一种情况, 其他情况以此类推:
a = 1
def func1():
print(a)
return a
def func2():
print(a)
a = a + 1
return a
这两个函数只有 func1 可以正常执行, func2 会抛出 UnboundLocalError 异常。前者比较好解释,局部作用域没有 a ,那么会从全局作用域中去查找这个 a 。
后者我只能这样解释,就是函数体在执行前会做预先检查。如果发现有赋值语句存在,就会认为该变量名处于局部作用域中。由于函数体中有 a = a + 1 ,所以函数只在局部作用域查找 a , 然后执行的时候,发现并没有 a 这个变量,故抛出异常。
我觉得这种解释非常的绕,而且不是很直观,很容易忘记。不知道各位 v 友有什么通俗一点的方式来描述这种行为~
1
est 2017-01-23 11:28:45 +08:00
global a
|
2
aragakiiyui OP @est ......晕,这个解释不了这个问题。
|
3
lightning1141 2017-01-23 12:13:35 +08:00
因为赋值语句的存在, Python 尝试在局部作用域 (即 locals 名字空间) 中新建一个对象关联. 其实只是局部变量跟全局变量变量名冲突了. 冲突之后 Python 因为按 LEGB 顺序查找变量, 发现 a 还没有在局部作用域绑定, 所以导致了 UnboundLocalError.
``` def test1(): a = a print(a) def test2(): x = a print(x) ``` 第一个没问题, 第二个报错. |
4
lightning1141 2017-01-23 12:19:14 +08:00
简单来说就是:
赋值导致了拥有这个变量名的变量只能在局部作用域查找 |
5
bxb100 2017-01-23 12:21:23 +08:00 via Android
加个 a = a 还报错吗
|
6
lightning1141 2017-01-23 12:26:28 +08:00 1
|
7
bxb100 2017-01-23 12:32:58 +08:00 via Android
@lightning1141 符合逻辑
|
8
qiu0130 2017-01-24 00:37:12 +08:00 1
|
9
phrack 2017-01-24 09:41:51 +08:00 1
以前写 c 程序的时候,偶尔也会有出乎意料的结果,但是我一直有个办法,就是反汇编直接跟踪执行流程。
python 也一样, import dis, dis.dis(func1), dis.dis(func2), 瞬间就明了了。 |
10
IanPeverell 2017-01-24 15:51:23 +08:00
func2() 里面加一个 global a 就不会抱错了,因为这样是为了让你在修改变量的时候提醒你,你有个全局变量和你要修改的变量名称相同。
( python 3.5.2) a = 1 def func1(): print(a) return a print(func1()) def func2(): global a a += 1 print(a) return a print(func3()) 这种情况下是不会报错的,如果仅仅是引用全局变量而不修改全局变量是不会报错的 |