Python中作用域的特别之处
def a(): a = [] def aappend(): a.append(1) aappend() print a def b(): b = 1 def bchange(): b += 1 # 等于b = b + 1 bchange() print b a() b()
输出结果如下:
[1] Traceback (most recent call last): File "E:\Python-2.7.5\py\test.py", line 16, in <module> b() File "E:\Python-2.7.5\py\test.py", line 12, in b bchange() File "E:\Python-2.7.5\py\test.py", line 11, in bchange b += 1 UnboundLocalError: local variable 'b' referenced before assignment
a函数输出正确,b函数报错说局部变量b在赋值前引用。
因为b函数中b被赋值(b += 1等价于b = b +1),b变成bchange中个一个局部变量,覆盖掉了b的外层作用域,所以找不到b的值。
而a函数中a是一个list,a.append()不属于对a赋值的操作,a的作用域依然在整个a函数中。
值得注意的是,python不会执行到赋值语句才会改变变量的作用域,如下例:
def c(): c = 1 def cchange(): b = c + 1 c = b cchange() print c c() Traceback (most recent call last): File "E:\Python-2.7.5\py\test.py", line 28, in <module> c() File "E:\Python-2.7.5\py\test.py", line 23, in c cchange() File "E:\Python-2.7.5\py\test.py", line 21, in cchange b = c + 1 UnboundLocalError: local variable 'c' referenced before assignment
如果是按照顺序执行到“b = c + 1”语句时,c仍然是外层变量,b应该得到值为2,结果却是找不到c的值,因为下一条语句"c = b"指定了c是局部变量。我们对代码稍作修改:
def c(): c = 1 def cchange(): b = c + 1 print b #去掉c = b cchange() print c c() #结果如下 2 1
结果b很自然地得到了值为2。
所以,只要一个代码块里有赋值语句,从一开始这个变量的作用域就变了,而且python不会去上层空间寻找变量名。