(7)名称空间和作用域
名称空间namespaces
名称空间就是存放名字与值绑定关系的内存空间
名称空间内部呈现的格式,是以字典的形式呈现给你看,即key=valus的格式,但是不是字典类型,只是呈现的方式是字典的样式
名称空间分为三种
内置名称空间:
1. 特点: 存放是python解释器自带的名字,len,print
2. 生命周期: 解释器启动则产生,解释器关闭则销毁
3. 函数的局部名称空间彼此隔离,但是全局名称空间与内置名称空间是所有函数共享的
4. 名称空间的嵌套关系是在函数定义(检测语法)就固定死的与调用位置无关,即无论在何处调用函数都必须老老实实地按照定义阶段规定的嵌套关系去查找名字
全局名称空间
1. 特点: 存放是全局的名字(没有任何缩进\顶头定义的名字)
x=10
y=20
def func():
pass
print(x)
if True:
x=1111
2. 生命周期: python文件执行时则创建,文件执行完毕则销毁
局部名称空间:
1. 特点: 在函数内定义的名字
2. 生命周期: 在函数调用时临时创建,函数调用完毕则立即销毁三 名称空间
总结:
加载顺序:
1、先产生内置名称空间(这个是一定会产生)
2、产生全局名称空间(这个是一定会产生)
3、如果调用函数则会临时产生局部名称空间(这不一定会产生)
名字的查找顺序:
从当前位置向上查找
全局的是全局调用
内置函数全局可以调用
全局作用域:内置名称空间+全局名称空间
特点:全局存活,全局有效
局部作用域:局部名称空间
特点:临时存活,函数内有效
嵌套关系
在定义的时候就已经固定好了嵌套关系,即局部没有去全局,全局没有去内置,不可能打破这个原则,所以不存在夸局查找
例:嵌套关系
x = 111
def f1():
x = 111
def f2():
x = 3333
print(x)
return f2
xxx = f1 #将f1的名称空间放入一个变量,供全局调用
def foo():
x = 1111
xxx()
PS:foo在调用xxx的时候,x内print开始查找f2当前层有没有这个对应的值,如果没有则去f1查找,f1没有则去全局查找,全局没有去内置,内置没有报错,所以并不会在foo层查找,这就是在定义的时候已经固定好了嵌套关系
例,查找的顺序
len = 111
def func():
len=2222 #这个是局部len
print(len) #这个运行结果时候,如果就近有一个匹配的名称空间,则直接回返回这个名称空间对应的值,如果没有则会去全局查找,即print这一层局部有len的值,则会返回这 个值222,如果没有则会进入全局查找返回len的值111
len = 111 #如果全局的len在这一层,则print时候也能查找到,就是因为加载顺序优先级,程序运行时候会先创建一个全局内置名称空间,也就是运行时所有全局的名称空间已经第 一时间创建好了
func() #查找逻辑,当前func在全局模式下,所以先去全局找,如果有,则直接运行函数内的代码,将运行产生的名字全部放入局部名称空间
PS:
PS:python按照缩进去判定级别,顶头没有任何缩进定义的函数或者变量就是全局下定义的名称空间,可以全局调用
例:名称空间和作用域
x = 'aaa'
def f1():
x = 1
def f2():
x = 2
def f3():
x = 3
print(x)
f3()
f2()
f1()
PS:f3层的print,如果当前f3没有则去f2层查找,如果f2层没有则去f1层查找如果,如果f1层没有则去全局查找,如果全局没有则去内置查找,内置也没有就报错