#Python笔记# —— 闭包

每日计划:2017.05.21

<思维导图>

概念

维基百科是这样说的:

闭包:英语Closure,又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使离开了创造它的环境也不例外。所以有另一种说法认为闭包 是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。

自由变量:定义在外部函数内,但是由内部函数引用(或使用)的变量

简单的说,是在一个函数A中,定义另一个函数B,这个B函数就是闭包,调用A函数当中传递的参数就是自由变量
举例:

def func1():
    a=1
    def func2()
        print var
    return func2 # python可以返回一个函数




闭包特点和作用

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



一个常见的错误代码

def func1():
    var=1
    def func2():
        var=var+1
        print var
        retrun var
    return func2()

func1()
#结果输出
......
UnboundLocalError: local variable 'var' referenced before assignment



前面的命名空间和作用域部分已经讲过类似的,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()
#结果输出

不过这样还是显得麻烦,python3中可以使用nonlocal a,声明a不是闭包中的局部变量


闭包应用实例

还没写完,先去上课

你可能感兴趣的