名称空间
存放名字与对象映射/绑定关系的地方变就叫名称空间,就好比变量名与变量值
内建名称空间
python 解释器提前定义好的 例如:print() len()
周期:python解释器运行则产生,python解释器关闭则销毁
全局名称空间
在py文件中编写的代码运行产生的名字都会存到全局名称空间
周期:py文件开始运行则产生,py文件运行结束则销毁
name = 'kevin' # 变量名name存入全局名称空间def index(): # 函数名index存入全局名称空间passif True:a = 1 # 变量名a存入全局名称空间for i in range(10) # 变量名i存入全局名称空间passwhile True:b = 2 # 变量名b存入全局名称空间
局部名称空间
函数的形参、函数内定义的名字都会被存放到局部名称空间
周期:函数体代码开始运行则产生,函数体代码运行结束则销毁
def index_1():c = 1 # 变量名c存入局部名称空间
作用域
作用域就是名称空间能够作用的范围
全局作用域
全局名称空间和内建名称空间中,“名字”属于全局范围。该范围内的“名字”全局有效(除非被删除),在任意位置都可以使用
a = 1 # 全局作用域的变量名adef index():print(a)index() # 结果输出全局作用域的变量名a# 1
局部作用域
局部名称空间中,“名字”属于局部范围。该范围内的“名字”(在函数调用时生成,函数调用结束后释放)局部有效(只能在函数内使用)
a = 1 # 全局作用域的变量名adef index():a = 10 # 局部作用域的变量名aprint(a) # 在局部找变量名aindex() # 结果输出局部作用域的变量名# 10print(a) # 结果输出全局作用域的变量名a# 1
global与nonlocal关键字
global关键字
若要在函数内修改全局名称空间中“名字”的值,当值为不可变类型时,则需要添加global关键字
若值可变类型,则不需要
a = 1def index_1():global a # 声明修改的是全局a,而不是产生新的aa = 10index_1()print(a)# 10
nonlocal关键字
若嵌套多层函数时,内层函数想要修外层函数局部名称空间中“名字”的值,可以使用nonlocal关键字(非全局)
a = 10def index_2():a = 1 # 1.声明局部变量adef index_3():nonlocal a # 3.声明修改的是外层局部作用域a,而不是产生新的aa = 2 # 4.将值2重新赋值给aindex_3() # 2.调用index_3()print(a) # 5.此时index_2()代码块中变量a被index_3()重新赋值2index_2() # 1. 调用index_2()函数# 2print(a)# 10
作用域优先级
全局作用域优先级
在全局作用域查找“名字”时,起始位置是全局作用域,所以先查找全局名称空间,没有找到,再查找内置名称空间,最后都没有找到就会抛出异常
局部作用域优先级
在局部作用域查找“名字”时,起始位置是局部作用域,所以先查找局部名称空间,没有找到,再去全局作用域查找,再查找内置名称空间,最后都没有找到就会抛出异常
补充
可以调用内建函数locals()和globals()来分别查看局部作用域和全局作用域的“名字”,查看的结果都是字典格式。在全局作用域查看到的locals()的结果等于globals()
