每日计划:2017.05.21
<思维导图>
</br>
概念
维基百科是这样说的:
闭包:英语Closure,又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使离开了创造它的环境也不例外。所以有另一种说法认为闭包 是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。
自由变量:定义在外部函数内,但是由内部函数引用(或使用)的变量
简单的说,是在一个函数A中,定义另一个函数B,这个B函数就是闭包,调用A函数当中传递的参数就是自由变量
举例:
def func1():
a=1
def func2()
print var
return func2 # python可以返回一个函数
</br>
</br>
闭包特点和作用
1、闭包的词法变量 既不属于全局名称空间,也不属于局部名称空间。与对象不同,对象存活在一个对象的名称空间,但是闭包变量存活在一个 函数 的名称空间和作用域。
2、闭包引用的自由变量将与函数一同存在,即使离开了创作它的环境也不例外,可以用来保护或隐藏一个变量,不会在调用后被垃圾回收机制(garbage collection)回收
3、闭包和类等有些类似,皆是对代码进行了一些封装,提高代码的可复用性
4、闭包可用于间接访问一个变量,但是不能修改外部环境的局部变量
5、闭包不会造成内存泄露
6、闭包有利于并行运算
def func1():
a=1
def func2():
a=8
print a
print a
func2()
print a
#结果输出
1
8
1
</br>
一个常见的错误代码
def func1():
var=1
def func2():
var=var+1
print var
retrun var
return func2()
func1()
#结果输出
......
UnboundLocalError: local variable 'var' referenced before assignment
</br>
前面的命名空间和作用域部分已经讲过类似的,python默认函数中=赋值语句左边皆为局部变量。例子中func2()函数则认定var=var+1左边的var为局部变量,然后接着找右边的var,但是找不到var具体值,于是报错。
解决方法就是 将a设置为一个容器。
def func1():
var=[1]
def func2():
var[0]=var[0]+1
print var[0]
return var[0]
func2()
func1()
#结果输出
<function func2 at 0x0000000002A81B38>
不过这样还是显得麻烦,python3中可以使用nonlocal a,声明a不是闭包中的局部变量
</br>
闭包应用实例
还没写完,先去上课