名称空间

存放名字与对象映射/绑定关系的地方变就叫名称空间,就好比变量名与变量值

内建名称空间

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()

Last modification:March 18, 2022
如果觉得我的文章对你有用,请随意赞赏