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不会去上层空间寻找变量名。

 

posted on 2013-08-13 14:55  SZlibraco  阅读(286)  评论(0编辑  收藏  举报