6.6 名称空间和作用域
6.6.1 名称空间
- 名称空间:存放名字(变量名/函数名)的空间
- 内置名称空间
- 全局名称空间
- 局部名称空间
- 内置名称空间
'str'.strip()
strip()是函数所有内置方法都是函数,这些函数被封装后具有某种功能'str'.strip() #存入内存空间
- 内置名称空间:len函数是python内置方法,python启用就会定义len函数,并且把len存入内存空间,这个内存空间就是叫做内置名称空间,类似于小整数池
# 函数先定义后调用
lis=[1,2,3]
len(lis)
#从来没有定义过len()
# len函数是python内置方法,python启用就会定义len函数,并且把len丢入内存空间,这个内存空间就是叫做内置名称空间,类似于小整数池
range()
dict()
list()
str()
- 生命周期:python启动就存在,python关闭就释放。
- 全局名称空间
- 全局名称空间:除了内置和局部就是全局。
- 生命周期:文件运行时存在,运行完毕就释放。
- 局部名称空间
- 局部名称空间:函数内部的都叫局部,函数内部定义的名字都放入了局部名称空间。
- 生命周期:函数运行时存在,函数运行完释放。
y=1 #全局
def f1():x=1 局部def f2(): #f2也是局部z=3 #局部f2()x+=1 #可以用
x=1#不可以用
c=4 #局
三者执行顺序
- 内置名称空间-->全局名称空间-->局部名称空间
三者查找顺序
- 从当前名称空间开始以查找,然后逐步往上。如果当前为局部,则局部->全局->内置
x=1
def f1():x=2 x=4print(x) #4
#x查找顺序: f1局部内找到x=2->x重新赋值为4def f2():print(x) #1
#x查找顺序;f2局部没有->全局找到x=1def f3():print(len)
#len查找顺序:f3局部没有->全局没有->内置找到len()
f1()
f2()
f3()
4
1
<built-in function len>
6.6.2 作用域
-
全局作用域适用于全局+内置,全局可以修改内置的,内置可以修改全局的。
-
局部作用域:只适用于局部范围,在局部定义的名字只能在局部获取 局部不能修改全局,全局不能修改局部。
-
函数与函数之间可能会有相同名字的变量,但是这两个变量毫无关系互不影响,作用域不同。
-
作用域关系在函数定义阶段就已经确定。
def f1():def f2():pass f2() #可以调用f2()#不能调用,因为f2作用域是f1内
def f1():def f2():print('f2 fun') return f2# f1() #相当于拿到f2
# f1()() #f2f2=f1()
f2()
f2 fun
#作用域关系在函数定义阶段就已经确定def f1():x=1def f2():print(1,x) #x搜索顺序:f2没有->f1找到。x=1return f2f2=f1()x=10def f3():x=15print(2,x) # 2 15f2()f3()
#输出1
2 15
1 1
6.6.3 globals & nonlocal(不推荐使用)
- globals:局部修改全局
- nonlocal :把局部改成外部,不能修改函数之外的,即不能修改全局
- globals
#globals:局部可以修改全局x=100
def f1():global x #声明x是全局的x=1print(x)print(x)
f1()
100
1
- nonlocal
#nonlocal :把局部改成外部,只能修改函数内部,不能修改全局#有nonlocal声明
x=100
def f1():x=1def f2():nonlocal x #声明x是外部,外部:函数嵌套内部的外部x=2f2()print(x) #有nonlocal,x往内层找 x是f2中的x,x=2return f2 f1()()
2
#没有nonlocal声明
x=100
def f1():x=1def f2():x=2f2()print(x) #没有nonlocal x从当前层开始往外层找,x=1,x是f1中的x#x查找顺序:f1找到,x=1return f2f1()()
1