与Python作用域有关的问题

value = 1

def foo():
    value = 2

foo()

print value

与上面代码类似的例子想必大家再熟悉不过了。这是一个阐述作用域的例子,它最终输出1。

代码中value 是一个全局变量,函数foo() 可以访问到这个全局变量,但不能改变这个全局变量指向的对象。所以,函数内对value 的赋值操作实际上创建的一个局部变量。

 

下面这段代码是我碰到的一个有意思的情况。

value = 1

def foo():
    if value:
        value = 0

foo()
print value

我们知道value 是一个全局变量,函数里访问了这个全局变量并判断其为真,然后进入判断语句对value 赋值。而全局中有一个名为value 的变量,函数内无法更改全局变量所指向的对象的。所以,此处的赋值应该会创建一个局部变量。理论上,程序仍输出1。

 

然而,结果是:

抛出了一个UnboundLocalError ,并提示我们局部变量在赋值前被引用。这就神奇了,之前的推断是错误的。

 

后面又做了如下实验:

value = 1

def foo():
    if not value:
        value = 0

foo()
print value

实际上只是将判断条件改了一下,让函数中判断语句的条件为False ,使赋值语句不执行。

结果仍是UnboundLocalError 异常。

 

思索了一番,我的理解是这样的:Python解释器解析到foo函数时,发现有一个对value 的赋值操作,就会把value 看作是一个局部变量。调用的时候就不再去全局中查找了,而仅仅在局部查找这个变量,而在上面的判断条件语句时,value 还没声明,所以抛出了这个异常。

 

本人能力有限,不知道有没有人有更深层的阐述,望加斧正。