1.命名空间
命名空间 namespace又称名称空间 :存放名字的地方,是对栈区的划分
有了命名空间,就可以在栈区中存放相同的名字,命名空间分三种:
1.内置命名空间:
存放的名字:python解释器内置的名字:如print、int、……
存活周期:python解释器启动则产生,python解释器关闭则销毁
2.局部命名空间:
存放的名字:只要不是函数内定义的,也不是内置的,都是全局命名空间
import os
x=10
if 10>3:
y=2
def func():
pass
存活周期:python文件执行则产生,python文件运行完毕后销毁
3.全局命名空间
存放的名字:调用函数时,运行函数体代码过程中产生的函数体内的名字
存活周期:在函数调用时存活,函数调用完毕后则销毁
def func(x=1,y=2):
print(x,y)
func()
func()
# 每调用一次,都会新产生一次
4.命名空间的加载顺序
内置命名空间--->全局命名空间---->局部命名空间
5.命名空间的加载顺序
内置命名空间<---全局命名空间<----局部命名空间
6.名字的查找优先级:当前所在的位置,向上一层一层查找
内置命名空间
全局命名空间
局部命名空间
如果在局部命名空间内:
局部命名空间--->全局命名空间---->内置命名空间
input=666
def func():
input=555
print(input)
func()#555
如果在全局命名空间内:
全局命名空间---->内置命名空间
input=666
def func():
input=555
func()
print(input)#666
def func():
input=555
func()
print(input)#<built-in function input>
从一个命名空间找不到,去另一个命名空间找,物理从层面上,三个空间并没有包含关系,而是区域划分
示例1:
def func():
print(x)
x=1111
func()#1111
示例2:
命名空间的“嵌套”关系是以函数定义阶段为准的,与调用位置无关
x=1
def func():
print(x)
def foo():
x=2
func()
foo()#1
示例3:函数嵌套定义
input=111
def f1():
def f2():
input=333
print(input)
input=222
f2()
f1()#333
示例4:
在函数定义的时候,虽然不会执行,但会监测函数体语法正确性,在此过程中,变量的命名空间就已经确定好了,所以一旦被调用,就会在确定好的命名空间内找变量,找不到就报错。
x=111
def func():
print(x)
x=222
func()#UnboundLocalError: local variable 'x' referenced before assignment
x=111
def func():
print(x)
# x=222
func()#111
2.作用域=》作用范围
1.全局作用域:内置命名空间、全局命名空间
1.全局存活
2.全局有效:被所有函数共享
x=11
def foo():
print(x,id(x))
def bar():
print(x,id(x))
foo()
bar()
# 11 1565551680
# 11 1565551680
2.局部作用域:局部命名空间的名字
1.临时存活
2.局部有效:函数内有效
LEGB 约定俗成的作用域查找范围,先从l(local)往外查找。了解即可。
#builtin
#global
def f1():
#e
def f2():
#enclosing
def f3():
#local
pass
3.global与nonlocal
global 想要在局部修改全局的不可变类型
x=111
def func():
global x
x=222
print(x)#111
func()
print(x)#222
nonlocal (了解):修改函数外层函数不可变类型变量名对应的值
x=0
def f1():
x=11
def f2():
global x
x=22
f2()
print('f1内的x:',x)
#f1()#f1内的x: 11
x=0
def f1():
x=11
def f2():
nonlocal x
x=22
f2()
print('f1内的x:',x)
f1()#f1内的x: 22