一、作用域
函数的命名空间可以作用域可以划分为:LEGB四种,使用缩进来规定。 不同的命名空间的变量可以同名。
本地 local 本地使用,在函数缩进中,代表着本地缩进
封闭 enclosing 在嵌套函数中使用,
全局 global 任何地方都能使用,模块的顶层
内置 Builtin 内置,比如 int,内置函数等。
1.1 作用域的范围 与 搜索次序
从里到外所搜:本地 -》封闭-》全局
1.2 作用域规则
搜索规则:本地 -》封闭-》全局 从里到外 一层层修改。
修改规则: 本地可以引用全局的变量,但是不可以修改上一级的变量。
(注意复杂的数据结构,list,dict 修改他们的二级数值,并不算修改本身。详见:深浅拷贝章节)
i = 1
deftest():
i+= 1 #等同与 i = i + 1 ,这里的i 都是全局变量。 在规则中,不可以修改全局变量。
test()
UnboundLocalError: local variable'i'referenced before assignment
对于复杂结构的数据:
li = [1,2,3,4]deftest():
li[0]= 100li.append(200) #对于复杂的数据节后,可以直接修改二级的,并不算修改本身
test()print(li)
结果:
[100, 2, 3, 4, 200]
二、内嵌函数
在一级函数内部,定义函数,可在内部直接运行函数,也可以返回函数,这就是内嵌函数,也叫做封闭作用域。
defcal(a, b):defadd(a,b):print (a+b)defsub(a,b):print(a-b)defmul(x,y):print (a*b)
add(a,b)
sub(a,b)returnmul
cal(1,3)()
三、闭包函数
闭包函数是内嵌函数的升级版本, 返回 内嵌函数名 与 自由变量(非全局变量,是一级函数的变量)的绑定体。
一般函数执行完毕,内部的变量的就消亡了,但是闭包的函数的存在一个封闭空间,不会在一级函数运行完毕而消亡。
defhellow():
s= 'i AM' # 自由变量
defsay():print(s)return say # 返回内嵌函数名,但是绑定了自由变量
x =hellow()
x()
闭包函数 也遵循了,不能修改上一级变量的特征。
defhellow():
s= 'i AM'
defsay():
s+= '' #修改上一级变量,报错
print(s)returnsay
x=hellow()
x()
运行结果:
UnboundLocalError: local variable's' referenced before assignment
四、修改上一级的变量
上面一直说不能修改和赋值,那一定要修改和赋值呢?
python中引进了 gloable 和 nolocal 两个关键字。
4.1 global
global的两个作用:
声明一个全局变量
在局部作用域想要对全局作用域的全局变量进行修改时,需要用到 global(限于字符串,数字)
deffunc():global a #声明为全局变量
a = 2
print(a)
func()print(a)
计算结果:2
2
4.2 nolocal
不能修改全局变量
在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变
defadd_b():
b= 42
defdo_global():
b= 10
print(b)defdd_nonlocal():
nonlocal b # 只对上一层起作用
b= b + 20
print(b)
dd_nonlocal()print(b)
do_global()print(b)
add_b()
计算结果:10
30
30
42