目录
名称空间与作用域
名称空间
名称空间(name spaces):
name = 'zkim'
就是在内存中开辟了一个新的空间,用来存放zkim
,而name
与zkim
具有绑定关系,我们能通过name
找到zkim
。那么name
又存放在哪呢?...其实在内存中有一块内存存储变量名与变量间绑定关系的空间,而这个空间称之为名称空间。
- 内置名称空间
内置名称空间:存放Python解释器自带的名字,如 print,len,int 等等。
生命周期:在Python解释器启动的时候生效,在解释器关闭的时候失效。
- 全局名称空间
全局名称空间:除了内置和局部的名字之外,其余都存放在全局名称空间。如 x,func,l,z
x = 1 # x 存放于全局名称空间print(x)l = [1, 2] # l 存放于全局名称空间print(l)if 3 > 2: if 4 > 3: z = 3 # z 存放于全局名称空间print(z)def func(): # func 存放于全局名称空间 passprint(func)
# 1# [1, 2]# 3#
生命周期:在文件执行时生效,在文件执行结束后失效。
- 局部名称空间
局部名称空间:用于函数调用期间,存放函数体产生的名字。如f2
def f1(): def f2(): # f2 在f1的局部名称空间中 print('from f2') f2() f1()
# from f2
生命周期:在文件执行时函数调用期间生效,在函数执行结束后失效。
名称空间的加载顺序
1:python解释器先启动,因而首先加载的是:内置名称空间。
2:执行test.py文件,然后以文件为基础,加载全局名称空间。
3:在执行文件的过程中如果调用函数,则临时产生局部名称空间。
名字的查找顺序
- 查找顺序只能是依次往上找:
内置名称空间--->全局名称空间--->内置名称空间
- 从当前所在的位置开始查找:
当前在局部名称空间时:局部--->全局--->内置
当前在全局名称空间时:全局--->内置
# len = 1 全局名称空间 没有依次往上查找def f1(): # len = 2 f1的局部名称空间 没有依次往上查找 def f2(): # len =3 f2的局部名称空间 没有依次往上查找 print(len) # 从f2的局部名称空间开始查找 len 的值 f2()f1()print(len) # 当全局中找不到的时候回去内置中查找
# 内置中查找的结果:
作用域
域指的就是区域,作用域即作用的区域。
全局作用域
全局有效,全局存活,包含内置名称空间和全局名称空间。
x = 1def func(): print(x)func()
1
- 局部作用域
局部作用域:局部有小,临时存储,只包含局部名称空间。
x = 1def func(): print(x) def func2(): x = 2 func()func2()
1
函数对象+作用域应用
def f1(): def inner(): print('from inner') return inner # 将函数名 inner 当作返回值f = f1() # f = innerdef bar(): f() # inner()bar()
# from inner
global 与 nonlocal 关键字
- global 与 nonlocal 能够修改多个变量,如:
# global x,y,z 依次以逗号隔开# nonlocal x,y,z 依次以逗号隔开
- global 关键字
# 修改类型为不可变数据类型name = 'jason' # 全局变量def f1(): name = 'nick' def f2(): global name # 修改全局变量的值 name = 'egon' f2()f1()print(name)
# egon
- nonlocal 关键字
name = 'jason'def f1(): name = 'nick' # 局部变量 def f2(): nonlocal name # 修改局部变量的值 name = 'egon' f2() print(name)f1()
# egon
- 注意点
1:在局部想要修改全局的可变类型,不需要任何声明,可以直接修改。
2:在局部如果想要修改全局的不可变类型,需要借助 global 声明,声明为全局的变量,即可直接修改。
lis = []def func(): lis.append(['jsaon','tank','nick','egon']) # 一个列表整体代表一个元素func()print(lis)
[['jsaon', 'tank', 'nick', 'egon']]