转自:http://www.weidianyuedu.com/
Python中的作用域
Python的作用域解析顺序为Local、Enclosing、Global、Built-in,也就是说Python解释器会根据这个顺序解析变量。
看一个简单的例子:
global_var = 0
def outer_func():
outer_var = 1
def inner_func():
inner_var = 2
print "global_var is :", global_var
print "outer_var is :", outer_var
print "inner_var is :", inner_var
inner_func()
outer_func()
结果为:
global_var is : 0
outer_var is : 1
inner_var is : 2
在Python中,关于作用域有一点需要注意的是,在一个作用域里面给一个变量赋值的时候,Python会认为这个变量是当前作用域的本地变量。
对于这一点也是比较容易理解的,对于下面代码var_func中给num变量进行了赋值,所以此处的num就是var_func作用域的本地变量。
num = 0
def var_func():
num = 1
print “num is :”, num
var_func()
问题一
但是,当我们通过下面的方式使用变量的时候,就会产生问题了:
num = 0
def var_func():
print “num is :”, num
num = 1
var_func()
结果如下:
UnboundLocalError: local variable ‘num’ referenced before assignment
之所以产生这个错误,就是因为我们在var_func中给num变量进行了赋值,所以Python解释器会认为num是var_func作用域的本地变量,但是当代码执行到print “num is :”, num语句的时候,num还是未定义。
问题二
上面的错误还是比较明显的,还有一种比较隐蔽的错误形式如下:
li = [1, 2, 3]
def foo():
li.append(4)
print li
foo()
def bar():
li +=[5]
print li
bar()
代码的结果为:
[1, 2, 3, 4]
UnboundLocalError: local variable ‘li’ referenced before assignment
在foo函数中,根据Python的作用域解析顺序,该函数中使用了全局的li变量;但是在bar函数中,对li变量进行了赋值,所以li会被当作bar作用域中的变量。
对于bar函数的这个问题,可以通过global关键字。
li = [1, 2, 3]
def foo():
li.append(4)
print li
foo()
def bar():
global li
li +=[5]
print li
bar()