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