名称空间
名称空间
一、名称空间分类
名称空间就是我们存储变量名、函数名、方法名的一个空间。
我们把名称空间分为三种:内置名称空间、全局名称空间、局部名称空间。
内置名称空间
内置名称空间存在与解释器中,当我们运行解释器的时候就会产生。所有的方法名都存在这里。
全局名称空间
全局名称空间在运行py文件的时候才会产生,内部存放一些变量名、函数名等。目前来说py文件之间的全局名称空间不互通。
name = 'jason'
if name:
age = 18
while True:
gender = 'male'
def index():
pass
class MyClass(object):
pass
name\age\gender\index\MyClass这些都是在全局名称空间中的
局部名称空间
在我们编写函数的时候局部名称空间并不会产生,当我们调用函数的时候才会产生局部名称空间。内部有一些函数内的变量名或内部嵌套函数的函数名。
二、名称空间存活周期极其作用域
每个名称空间的存活周期和作用域都有所不同,为了方便理解,我们用表格进行对比:
存活周期
类型 | 存活周期 |
---|---|
内置名称空间 | 当我们运行解释器的时候就会产生内置名称空间,当我们关闭解释器的时候内置名称空间才会关闭,如果我们想修改内置名称空间的内容,也就意味着我们要去修改python解释器。 |
全局名称空间 | 当我们运行一个py文件的时候就会产生这个文件对应的全局名称空间,当这个py文件停止运行的时候就会关闭这个名称空间,如果我们想要修改全局名称空间中的内容直接在py文件中修改即可。 |
局部名称空间 | 局部名称空间在我们调用函数的时候会产生,当函数运行结束就会自动关闭,如果函数内嵌套有其他函数,那么这个局部名称空间不会函数调用运行结束后关闭,而是会在内部嵌套的函数也运行结束后才关闭。 |
作用域
类型 | 作用域 |
---|---|
内置名称空间 | 因为来自解释器,所有内置名称空间的作用域是全局有效 |
全局名称空间 | 因为全局名称空间来自py文件,所以通常情况下一个全局名称空间只对应一个py文件 |
局部名称空间 | 局部名称空间值能作用到函数内部的代码 |
三、名字的查找顺序
ps:这里需要注意,名称的调用和函数一样,需要先定义后使用,否则报错
在不同的名称空间下查找变量名有不同的查找顺序:
内置名称空间
当我们在内置名称空间中调用变量、方法的时候,会直接在内置名称空间中查找,如果没有就直接报错。\
全局名称空间
当我们在全局名称空间调用变量、方法的时候,会先在全局名称空间中查找。如果没有就会去内置名称空间中查找,再找不到也会报错。
局部名称空间
这里我们拿一个特殊例子来进行说明,当我们在一个函数的内部嵌套一个函数,在内部的函数中调用变量、方法的时候,会现在它自己对应的那个局部名称空间内部的局部名称空间中查找,如果没有就去外部的局部名称空间中查找,如果还没找到就去全局名称空间中查找,再没找到就是去内置名称空间中查找,最后还没找到的话就会报错。
关于查找顺序的举例:
1、互相没有关系的几个函数生成的局部名称空间并不能互通
def func1():
name = 'jason'
print(age)
def func2():
age = 18
print(name)
# 这里会直接报错
2、局部名称空间嵌套案例
x = '干饭了'
def func1():
x = 1
def func2():
x = 2
def func3():
print(x)
x = 3
func3()
func2()
func1()
这里是运行流程讲解:
这里如果把print(x)和x=3的运行顺序互换就会输出三,如果把x=3删了,就会输出func3外层中的x=2的结果
当我们不清楚调用的是哪个名称空间中的变量的时候,需要根据程序运行的流程进行分析,然后就可以得到准确的答案。
四、global和nonlocal方法
global方法
global方法的作用是在局部名称空间内修改全局名称空间中的变量名绑定的值。
money = 666
def index():
global money
money = 123
index()
print(money)
"""
局部名称空间直接修改全局名称空间中的数据
"""
nonlocal方法
nonlocal方法的作用是在出现嵌套函数的时候,在内层函数的局部名称空间中修改外层函数的局部名称空间中的变量名绑定的值
def index():
name = 'jason'
def inner():
nonlocal name
name = 'kevin'
inner()
print(name)
index()
'''
内层局部名称空间修改外层局部名称空间中的数据
'''