一、名称空间namespaces:存放名字的空间,是对栈区的划分,有了名称之后,就可以在栈区中存放相同的名字,详细的,名称空间分为三种。
1.1 内置名称空间
存放的名字:存放的是python解释器内内置的名字
存活周期:python解释器启动则产生。python解释器关闭则销毁。
'''
>>> print
<built-in function print>
'''
1.2 全局名称空间
存放的名字:只要不是函数内定义,也不是内置的,剩下的都是全局孔家名称。
存活周期:python文件执行则产生,python文件运行完毕后销毁。
1.3 局部名称空间
存放的名字:在调用函数时,运行函数体代码过程中产生的函数内的名字。
存活周期:在调用函数时存活,函数调用完毕后则销毁。
def func():
a = 111
b = 222
func()
1.4 名称空间的加载顺序
内置名称空间 > 全局名称空间 > 局部名称空间
1.5 销毁顺序
局部名称空间 > 全局名称空间 > 内置名称空间
1.6 名字的查找优先级: 当前所在位置向上一层一层查找
内置名称空间
全局名称空间
局部名称空间
如果当前在局部名称空间
局部名称空间–>全局名称空间 -->内置名称空间
# 3最后是内置
#input = 333 # 2 在全局
def func():
#input = 444 # 1 # 先局部
print(input)
func()
如果当前在全局名称空间
全局名称空间–>内置名称空间
#在内置
#input = 333 # 1先全局
def func():
input = 444
func()
print(input)
示范1:
x = 111
def func():
print(x)
func()
def func():
print(x)
x = 111
func() #最终结果相同
示范2:名称空间的“嵌套”关系是以函数定义阶段为准,与调用位置无关
x = 1
def func():
print(x)
def foo():
x = 222
func()
foo()
示例3:函数嵌套定义
#input = 111 #3
def f1():
#input = 222 #2
def f2():
#input = 333 #1
print(input)
f2()
f1()
二、作用域–>作用范围
全局作用域: 内置名称空间、全局名称空间
1.全局存活
2.全局有效:被所有函数共享
x = 111
def foo():
x = 11
print(x,id(x))
def bar():
y = 222
print(x,id(x))
foo()
bar()
局部作用域:局部名称空间的名字
1.临时存活
2.局部有效:函数内有效
def foo(x):
def f1():
def f2():
print(x)
LEGB
#built-in
#global
def f1():
#enclosing
def f2():
#enclosing
def f3():
#local
pass
三、global与nonlocal
示范1:
x = 111
def func():
x =222
func()
print(x)
示范2:如果在局部想要修改全局的名字对应的值(不可变类型),需要用global声明。
x = 111
def func():
global x # 声明这个名字是全局的名字,不要再造新的名字了
x =222
func()
print(x)
示范3:
l = [111,222]
def func():
l.append(333)
func()
print(l)
nonlocal(了解):修改函数外层函数包含的名字对应的值
x = 0
def f1():
x = 11
def f2():
#global x
#nonlocal x
x = 22
f2()
print('f1内的x:',x)
f1()