目录
一, 名称空间
1. 内置名称空间
2. 全局名称空间
3. 局部名称空间
4. 加载顺序
5. 查找顺序
二, 作用域
1. 全局作用域
2. 局部作用域
3. 注意点
4. 函数对象与作用域应用
三, 补充知识点 (不推荐使用)
1.global 关键字
2.nonlocal 关键字
3. 注意点
函数内部的函数只能在函数内部调用, 不能再函数外部调用, 要想知道为什么, 我们就需要了解名称空间和作用域
一, 名称空间
名称空间 (name spaces): 在内存管理那一章节中, 我们知道变量的创建其实就是在内存开辟了一个新的空间. 但是变量名的存储之前一直没有提及, 其实在内存中有一块内存存储着变量名与变量之间绑定关系的空间, 这个空间叫做名称空间
1. 内置名称空间
1. 内置名称空间: 存放 python 解释器自带的名字, 比如
int,float,len,strip
2. 生命周期: 在 python 解释器启动时生效, 在 python 解释器关闭时失效
2. 全局名称空间
1. 定义: 除了内置和局部的名字之外, 其余都放在全局名称空间. 如下面的 a,f,l,i
2. 生命周期: 在文件执行时生效, 在文件执行结束后失效
- a = 0
- def f():
- pass
- l = [2,'k']
- if 2>1:
- if 0<1:
- i = 6
3. 局部名称空间
1. 定义: 用于存放函数调用期间函数体产生的名字. 比如下面的 f2
2. 生命周期: 在文件执行时函数调用期间时生效, 在函数执行结束后失效
- def f():
- def f2():
- print('ha')
- f2
- f()
4. 加载顺序
由于. py 文件是由 python 解释器打开的, 因此一定是在 python 解释器中的内置名称空间加载结束后, 文件才开始打开, 这个时候才会产生全局名称空间, 但文件内有某一个函数被调用的时候, 才会开始产生局部名称空间, 因此名称空间的加载顺序为: 内置名称空间 ----> 全局名称空间 ----> 局部名称空间
5. 查找顺序
由于名称空间是用来存放变量名与值之间的绑定关系的, 所以但凡要查找名字, 就必须从名称空间中的三者之一找, 查找顺序是, 从当前的所在位置开始查找, 如果当前所在的位置为局部名称空间, 则查找顺序为: 局部名称空间 ----> 全局名称空局 ----> 内置名称空间 (也就是从当前位置开始, 只会往外找)
- x = 0
- y = 1
- def f():
- x = 66
- y = 233
- print(x,y)
- f() # 66 233
- ```python
- x = 0
- def f():
- print(x)
- x = 6
- f() #6
- ```
二, 作用域
作用域就是作用的区域
== 只需要记住: 全局变量和局部变量, 可能名字一样, 但是两者根本不是同一种 ==
1. 全局作用域
全局作用域: 全局有效, 全局存活, 包含内置名称空间和全局名称空间
- x = 6
- def f():
- print(x)
- f() # 6
2. 局部作用域
局部作用域: 局部有效, 临时存储, 只包含局部名称空间
- def f1():
- def f2():
- def f3():
- print(x)
- x = 1
- f3()
- f2()
- f1() # 1
3. 注意点
作用域关系在函数定义阶段就固定死了, 与函数的调用无关
- x = 1
- def f(): # 函数定义阶段
- print(x) # 由于 f() 函数的局部作用域没有 x, 所以会先去全局找, 此时 x=1
- def f2():
- x = 6 # 这个 x 只能在 f2() 函数的局部作用域起作用, 对 f() 函数没有丝毫影响
- f()
- f2() # 1
4. 函数对象与作用域应用
- def f():
- def f1():
- print('hah')
- return f1
- a = f()
- def f2():
- a()
- f2() # hah
三, 补充知识点 (不推荐使用)
1.global 关键字
作用: 修改全局作用域中的变量
- x = 1
- def f():
- x = 6
- def f2():
- x = 233
- f2()
- f()
- print(x) # 在当前位置查找, 所以是全局作用域的 x=1
- x = 1
- def f():
- x = 6
- def f2():
- global x # 可以将局部变量变为全局变量
- x = 233
- f2()
- f()
- print(x) # 233
2.nonlocal 关键字
修改局部作用域中的变量
- x = 1
- def f():
- x = 6
- def f2():
- x = 233
- f2()
- print(x)
- f() # 6
- x = 1
- def f():
- x = 6
- def f2():
- nonlocal x # 可以使内部函数变量在外部也能使用, 但不能修改为全局变量
- x = 233
- f2()
- print(x)
- f() # 233
3. 注意点
1. 在局部想要修改全局的可变类型, 不需要任何声明, 可以直接修改
2. 在局部想要修改全局的不可变类型, 需要借助 global 声明, 声明为全局变量
- lis = []
- def f():
- lis.append(1)
- # 函数调用前
- print(lis) # []
- # 函数调用后
- f()
- print(lis) # [1]
来源: http://www.bubuko.com/infodetail-3077505.html