mirror of
https://github.com/apachecn/ailearning.git
synced 2026-02-11 06:15:22 +08:00
323 lines
3.6 KiB
Markdown
323 lines
3.6 KiB
Markdown
# 作用域
|
||
|
||
在函数中,`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
|
||
<function len>
|
||
```
|
||
|
||
## 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` 所在的作用域寻找。 |