python之闭包精讲

【python之闭包精讲】很多语言都有闭包,那么闭包究竟是什么呢?来看一个简单的例子 。
def outer(x):x+=1def inner():print(x)return x*5return inner()a = outer(1)print(a)a= outer(2)print(a)a=outer(3)print(a)
首先看上述代码,上述代码就体现了如何产生一个闭包,Outer是我定义的一个外函数 , 当x变量加完1的时候,注意 , 此时并不执行inner函数,而是返回了内部函数inner,这里注意一点 , 如果后面的inner不带括号,那么outer外部函数最后返回的便是内部函数inner的引用,但是加了括号之后,就表示要执行inner()函数 。把inner函数的结果返回给了最后接收的a变量里了 。下面看执行结果 。

python之闭包精讲

文章插图
看到这大家会奇怪一个问题,按照正常的内存释放顺序来看,x变量是不存在的了,因为在outer函数返回之前,这段内存就该被释放,那么这就是闭包的优势的体现了,那么总结一下,闭包=函数块+定义函数时的环境 , outer就是函数块,x就是环境,当然这个环境可以有很多,不止一个简单的x 。所以闭包的本质是什么?当外部函数执行 时,发现内部函数要用到我的局部变量,那么我就把局部变量临时绑定到内部函数里以供使用 。这里其实说的不全对?为什么呢?下面看一个上一个例子的变形 。
代码如下:
def outer(x):def inner():x=x+1return x*5return inner()a = outer(1)print(a)a= outer(2)print(a)a=outer(3)print(a)
结果如下:
python之闭包精讲

文章插图
为什么呢?这里涉及到一个新知识点,就是中的变量访问LEGB顺序,就是local--- 。什么意思呢?就是如果查找变量先从本地作用域找,如果没找到就到外层作用域找,还没找到就去全局作用域找,如果还没找到,就去内置的变量里去找,如果还没找到就抛出异常 。那么分析一下上面的例子,首先,这是一个典型错误,是什么呢?就是闭包的内部函数不允许修改外部作用域的变量 。为什么呢?分析如下,当在内部执行x=x+1的时候,当x变量做左值的时候,就相当于修改了原来x变量的引用,相当于在本地作用域又有了一个新的x变量,可是我们知道,本地作用域并没有x,所以当然会抛出异常,所以只要不修改外部作用域与全局作用域的变量,那么在闭包里的内函数可以随意操作这些变量 。
那么说了这么多 , 闭包究竟有什么用呢?
第一 装饰器的实现依赖闭包
第二 函数式编程经常用到闭包 , 闭包对数据的持久化以及按配置产生不同的功能,是很有帮助的
第三 面向对象编程也经常用到闭包 。