系列文章目录
文章目录
一、命名空间(namespace)
假设有一所学校,里面有十个名叫张三的同学。这时,王校长要李老师去把张三找来。
如果没有分班,所有的张三都在同一个大教室里上课,那么李老师就不知道该找哪个张三了。
但如果有了分了班,每个班只有一个张三,且不会有重名的同学,那么李老师就会询问校长要找的张三的班级,从而很快的把张三找来。
- 含义:上述例子中的”班级“就相当于命名空间,可以把相同名称的变量分隔开来,避免名称方面的冲突。
python解释器把内存的栈区分为三块,对应三种命名空间:
1. 内置命名空间
- 存放的名称:存放python解释器内置的各种名称,如print。
- 存活周期:开始—python解释器启动;结束—python解释器关闭。
2.全局命名空间
- 存放的名称:除了函数内部和类内部定义的名称,以及内置的名称外,都属于全局名称空间。
- 存活周期:开始—程序开始运行;结束—程序运行结束。
3.局部命名空间
- 存放的名称:函数内部以及类内部的名称,如函数内部定义的普通变量的名称。
- 存活周期:开始—函数被调用时;结束—函数执行完毕。
4. 命名空间的加载、查找顺序
-
加载顺序:
内置—>全局—>局部
-
查找顺序:
局部—>全局—>内置
注意:只会从左往右查找,如果当前在全局,只会向右查找全局和内置,不会查找局部。
二、作用域
- 含义:作用域就是指一个变量的作用范围。
1. 四种作用域:
-
局部作用域(local)
函数中定义的变量的作用域叫做局部作用域。 -
闭包作用域(enclosing)
嵌套函数中,外层函数的局部作用域叫做闭包作用域。def foo(): a = 1 # 名称a就属于闭包作用域 def bar(): pass
-
全局作用域(global)
范围:模块级别定义的变量的作用域叫做闭包作用域,比如在一个py文件内的,定义在所有函数和类外面的变量,它们的作用域就是全局作用域。
-
内建作用域(build-in)
范围:python解释器内部变量的作用域,如print的作用域就是内建作用域。
2. 变量查找顺序
LEGB规则:Local 局部 —> Enclosing 闭包 —> Global 全局 —> Built–in python内建
3. 修改作用域
修改作用域,在底层其实就是修改了命名空间
-
global关键字
该关键字会使变量的作用域变成全局作用域。
-
nonlocal关键字
该关键字会使变量的作用域向上升一级。比如:使嵌套函数内层变量的作用域,变成闭包作用域。
def foo(): a = 1 # 名称a就属于闭包作用域 def bar(): nonlocal a # 此处a的作用域就与外层函数中的a相同了,两者处于同一个命名空间 pass