一、名称空间
1、定义:namespace,栈区是存放名字的地方,对其进行划分后产生了名称空间的概念,每个划分块为不同的名称空间 ,不同的名称空间可以存放相同的名字。
2、三种分类:
①内置名称空间:用于存放python解释器内置名字,如 print,input 等,该空间于python解释器启动时产生,python解释器关闭则销毁。
②全局名称空间:用于存放非内置名称且非函数内定义的名字,如主体程序定义的变量名,函数名等,该空间于python文件执行时产生,python文件运行完则销毁。
③局部名称空间:用于存放函数内函数体代码产生的名字,如函数内定义的变量名,嵌套定义的函数名等,该空间于函数调用产生,函数调用完则销毁。
3、顺序及优先级:
①名称空间的加载顺序:内置名称空间===》全局名城空间===》局部名称空间。
②名称空间的销毁顺序:局部名称空间===》全局名称空间===》内置名称空间。
③名字查找的优先级:以当前位置为起始,扩大范围查找直至找到该名字所对应值,则以此值为准。
二、作用域:即名字有效范围。
1、全局作用域:内置名称空间内的名字及全局名称空间内的名字,全局存活,被所有其他函数共享。
2、局部作用域:局部名称空间内的名字,临时存活,只在函数内有效。
三、相对名称空间:当一个函数嵌套一个函数时,子函数内的名字存于自己的局部名称空间,而主函数内与子函数同级的名字对子函数而言则是介于自己的局部名称空间与全局名称空间之间的外局部名称空间,这个相对而言的外局部名称空间的范围高于自己的局部名称空间而小于全局名称空间。
四、global与nonlocal
1、global:如果在局部名称空间内想要修改全局的名字对应的不可变类型的值,可以用global声明。若值为可变类型,局部名称空间内的修改可以只改变其值,而不改变可变类型本身与名字的绑定关系,这样局部修改会使得全局一起被修改。
x = 222 def func(): global x x = 111 # 通过global声明 x 为全局变量,这样在局部名称空间内修改 x 的值,等于在全局修改 func() print(x) # 结果为 111 l = [1,2,3] def func(): l[0] = 4 # 局部内没有 l ,所以此处 l 即全局的l,修改了 l 中的元素,而 l 本身内存地址并未改变 func() print(l) # 结果为 [4, 2, 3]
2、nonlocal:修改子函数的外局部名称空间的名字对应的值。与global同理,通过nonlocal声明,自身名称空间的名字的值发生改变会影响其,也是用于不可变类型的情况,可变类型无需这样的操作。
def f1(): x = 111 print(x) # 结果为 111 def f2(): nonlocal x x = 222 f2() print(x) # 结果为 222 f1()