名称空间
名称空间就是存放名字的地方,是对栈区的划分
有了名称空间之后,就可以在栈区中存放相同的名字,详细的名称空间,分为三种:内置名称空间、全局名称空间、局部名称空间
内置名称空间
内置名称空间存放的是python解释器内置的名字,如print、input、len
存活周期:python解释器启动则产生,python解释器关闭则销毁
全局名称空间
存放的是顶级的名字,只要不是函数内定义、也不是内置的,剩下的都是全局名称空间的名字
存活周期:python文件执行则产生,python文件运行完毕后销毁
x = 10 # 顶头写
def func(): # 是全局
x = 11 # 不是顶头写 不是全局
print(x)
if 1: # 是全局
y = 123 # 是全局
局部名称空间
函数内的名字,在调用函数时,运行函数体代码过程中产生的函数内的名字
存活周期:在调用函数时则产生,函数调用完毕后则销毁
名称空间的加载顺序(产生顺序)
内置名称空间>全局名称空间>局部名称空间
销毁顺序
局部名称空间>全局名空间>内置名称空间
名字的查找优先级:当前所在的位置向上一层一层查找
内置名称空间
全局名称空间
局部名称空间
如果当前在局部名称空间:局部名称空间—>全局名称空间->内置名称空间
# input=333
def func():
# input=444
print(input)
func()
如果当前在全局名称空间:全局名称空间->内置名称空间
def func():
input=444
func()
print(input)
示范1:
def func():
print(x)
x=111
func()
名称空间可以理解为一层套一层的关系,问题是嵌套关系是在函数定义阶段生成的,
非常重要的结论:名称空间的"嵌套"关系是以函数定义阶段为准,与调用位置无关
# 示范2:名称空间的"嵌套"关系是以函数定义阶段为准,与调用位置无关
x=1
def func():
print(x) # 1
def foo():
x=222
print(x) # 222
func()
print(x) # 222
foo()
x=1
def func():
print(x) # 报错
因为局部名称空间里有x,所以x找的是局部内的x 局部内x在print下面,所以报错x未定义
x = 222
func()
作用域-》作用范围
全局作用域
全局作用域:内置名称空间、全局名称空间
1、全局存活
2、全局有效:被所有函数共享
x=111
def foo():
print(x,id(x))
def bar():
print(x,id(x))
foo()
bar()
print(x,id(x))
局部作用域
部作用域: 局部名称空间的名字
1、临时存活
2、局部有效:函数内有效
# 案例1
x = 10
def func(x):
x = 20
print(x)
func(x)
print(x)
# 案例2
x = [1,2,3]
def func():
x[0]=123
func()
print(x) # 可变类型 局部可以改全局
# 案例3
x = 10
def func():
global x # 可以将局部改值传给全局
x = 20
func()
print(x)
x = 10
def f1():
x = 111
def f2():
nonlocal x
x = 222
f2()
print(x)
print(x)