一、名称空间(namespace)和作用域
名称空间就是将栈区分成了几块,如:内置名称空间、全局名称空间、局部名称空间
名称空间实现了在栈区可以存在相同名称的变量,不至于在遇到同名变量时将原来的变量覆盖。
其中内置名称空间和全局名称空间称为全局作用域,局部名称空间称为局部作用域。
1、内置名称空间:只有一个
存放python解释器内置的名字。
python解释器启动,就会创建内置名称空间,而python解释器一关闭,内置名称空间就会被销毁。
2、全局名称空间:可以有多个
Python文件内定义的变量名,包括函数名、类名、模块名
要排除函数内部定义的名字(包括函数的参数)
只要不是函数内部定义的名字,也不是内置的名字,剩下的都属于全局名称空间。
全局名称空间会在Python文件执行之前产生,Python文件运行完毕后销毁。
3、局部名称空间:可以有很多个
函数内部定义的名字(包括函数的参数)
在函数调用时产生,函数调用结束后销毁。
4、名称空间的查找优先级
局部名称空间>全局名称空间>内置名称空间
名称的查找顺序是以定义阶段为基准,不与调用阶段的顺序没有关系,举例”
x = 10
def func1():
print(x)
def func2():
x = 20
func1()
func2()
#此处输出的结果是10,说明名称的查找是以定义阶段为基准的
5、全局作用域:内置名称空间、全局名称空间
全局存活、全局有效、
6、局部作用域:局部名称空间
临时存活、局部有效
LEGB
B:built-in
G:global
E:enclosing
L:local
7、global
global主要针对的是局部想要修改全局的名字对应的不可变类型的值,比如函数内调用全局变量,调用前需要用:global 变量名 声明一下此变量是全局变量。
可变类型可以不用global声明,直接调用方法。
8、nonlocal
声明变量不是当前这一层,因此就会去上一层找这个变量。举例:
x = 10
def func1():
x = 20
def func2():
nonlocal x #此处声明后表示x是上一层x=20处的x
x = 30
print(x) #此处x的值是20
func2()
print(x) #此处x的值是30
使用nonlocal声明的变量必须在封闭空间里面存在这个变量,否则即使全局存在这个变量,在运行时候也会报错。