15----名称空间和作用域
一。名称空间
1/名称空间(namespace):存放名字的地方,是对栈区的划分,有了名称空间之后就可以在栈区中存放相同的名字,详细的名称空间分为三种,每个名称空间是独立的
Ⅰ内置名称空间(built_in)
存放的名字:python解释器内置的名字比如关键字
存活周期:python解释器启动则产生,python解释器关闭则销毁
Ⅱ全局名称空间
存放的名字:只要不是函数内定义也不是内置的,剩下的都是全局名称
存活周期:python文件执行则产生,python文件运行完毕后销毁
Ⅲ局部名称空间
存放的名字:在调用函数时运行函数体代码过程中产生的函数内的名字
存活周期:调用函数时产生,函数调用完毕后销毁,同一个函数调用几次就产生几个局部名称空间
2/名称空间加载顺序
内置名称空间》全局名称空间》局部名称空间
3/名称空间销毁顺序
局部名称空间》全局名称空间》内置名称空间
4/名称空间查找优先级:从当前位置,一层一层查找
Ⅰ 如果当前在局部名称空间
input = 456
def fun():
input = 123
print(input)
fun()
Ⅱ 如果当前在全局名称空间
input = 456
def fun():
input = 123
fun()
print(input)
5/名称空间的‘嵌套关系’:以函数定义阶段为准,与调用位置无关,名称空间在栈区中是独立的,这里的嵌套可以理解为不同的名称空间都存在同样的变量名
x = 10
def fun(x):
print(x)
def foo():
x = 20
fun(x)
foo()
x = 111
def func():
print(x) # 以函数定义阶段为准,定义阶段已经产生了局部变量,只是这个局部变量是在定义前被调用。
x = 222
func()
二。作用域
Ⅰ 全局作用域:内置名称空间&全局名称空间
1全局存活
2全局有效,被所有函数共享
Ⅱ 局部作用域:局部名称空间
1临时存活
2局部有效:函数内有效
三。global & nonlocal
1/global-----可以在局部中修改全局变量的值,前提是全局变量是不可变类型
Ⅰ 不可变类型
x=111
def func():
global x # 声明x这个名字是全局的名字,不要再造新的名字了
x=222
func()
print(x)
Ⅱ 可变类型---在局部修改全局变量不需要用global进行声明
l=[111,222] def func(): l.append(333) func() print(l)
2/nonlocal------修改函数外层函数包含的名字对应的值(不可变类型)
x=0
def f3():
x=9
def f1():
x=11
def f2():
nonlocal x
x=22
f2()
print('f1内的x:',x) # 22
f1()
print('f3',x) # 9
f3()
print(x) # 0