05.15 作用域
作用域
在函数中,Python 从命名空间中寻找变量的顺序如下:
local function scopeenclosing scopeglobal scopebuiltin scope
例子:
local 作用域
1def foo(a,b):
2 c = 1
3 d = a + b + c
这里所有的变量都在 local 作用域。
global 作用域
1c = 1
2def foo(a,b):
3 d = a + b + c
这里的 c 就在 global 作用域。
global 关键词
使用 global 关键词可以在 local 作用域中修改 global 作用域的值。
1c = 1
2def foo():
3 global c
4 c = 2
5
6print c
7foo()
8print c
1
2
其作用是将 c 指向 global 中的 c。
如果不加关键词,那么 local 作用域的 c 不会影响 global 作用域中的值:
1c = 1
2def foo():
3 c = 2
4
5print c
6foo()
7print c
1
1
built-in 作用域
1def list_length(a):
2 return len(a)
3
4a = [1,2,3]
5print list_length(a)
3
这里函数 len 就是在 built-in 作用域中:
1import __builtin__
2
3__builtin__.len
<function len>
class 中的作用域
| Global | MyClass |
|---|---|
var = 0 MyClass access_class |
var = 1access_class |
1# global
2var = 0
3
4class MyClass(object):
5 # class variable
6 var = 1
7
8 def access_class_c(self):
9 print 'class var:', self.var
10
11 def write_class_c(self):
12 MyClass.var = 2
13 print 'class var:', self.var
14
15 def access_global_c(self):
16 print 'global var:', var
17
18 def write_instance_c(self):
19 self.var = 3
20 print 'instance var:', self.var
| Global | MyClass | obj |
|---|---|---|
var = 0 MyClass [ access_class] obj |
var = 1access_class |
1obj = MyClass()
查询 self.var 时,由于 obj 不存在 var,所以跳到 MyClass 中:
| Global | MyClass | obj |
|---|---|---|
var = 0 MyClass [ access_class self] obj |
var = 1access_class |
1obj.access_class_c()
class var: 1
查询 var 直接跳到 global 作用域:
| Global | MyClass | obj |
|---|---|---|
var = 0 MyClass [ access_class self] obj |
var = 1access_class |
1obj.access_global_c()
global var: 0
修改类中的 MyClass.var:
| Global | MyClass | obj |
|---|---|---|
var = 0 MyClass [ access_class self] obj |
var = 2access_class |
1obj.write_class_c()
class var: 2
修改实例中的 var 时,会直接在 obj 域中创建一个:
| Global | MyClass | obj |
|---|---|---|
var = 0 MyClass [ access_class self] obj |
var = 2access_class |
var = 3 |
1obj.write_instance_c()
instance var: 3
1MyClass.var
2
MyClass 中的 var 并没有改变。
词法作用域
对于嵌套函数:
1def outer():
2 a = 1
3 def inner():
4 print "a =", a
5 inner()
6
7outer()
a = 1
如果里面的函数没有找到变量,那么会向外一层寻找变量,如果再找不到,则到 global 作用域。
返回的是函数的情况:
1def outer():
2 a = 1
3 def inner():
4 return a
5 return inner
6
7func = outer()
8
9print 'a (1):', func()
a (1): 1
func() 函数中调用的 a 要从它定义的地方开始寻找,而不是在 func 所在的作用域寻找。