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