python闭包
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python闭包相关的知识,希望对你有一定的参考价值。
声明 :初学python,此文主要作为笔记,知识面浅,若理解有误请多担待,指出错误更是感激不尽!
闭包 :当函数存在嵌套,并且子函数引用了父函数中的变量,可以访问这些变量的作用域就形成闭包。如果子函数没有访问父函数中的变量,就不存在闭包,闭包每次运行是能够记住引用的外部作用域的变量的值。形象点说就是有一个大盒子,里面有个小盒子,小盒子里面用到的一些东西是来自外部的大盒子的,那么这些来自大盒子的东西,就是闭包。
接下来全部使用例子来解释闭包!
例子 一
#这里定义的是一个求和函数 def lazy_sum(*args): def sum(): #我就是闭包!因为我引用了外部函数lazy_sum的局部变量args ax = 0 for n in args: ax = ax + n return ax return sum #注意这里返回的是一个函数,返回函数(闭包)的特点看下面的例子 f = lazy_sum(1,2,3) print(f()) #输出 6
可能应该略微知道闭包是个啥东西了,但是小心!返回的函数是没有马上执行的!直到被调用了才执行,所以这里有坑!什么坑呢?看例子!如果理解了下面的例子,那么你对闭包的理解和使用就更进一步了!
例子 二
#下面代码输出并非1、4、9而是9、9、9 def count(): fs = [] for i in range(1, 4): def f(): return i*i #先把局部变量i存起来,但是并没有马上执行 fs.append(f) return fs f1, f2, f3 = count() #等到执行的时候局部变量已经是3,所以说 #打印出来的结果不是1、4、9而是9、9、9! print(f1()) print(f2()) print(f3()) #因此返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。 #那硬是要使用循环变量怎么办?既然i属于外部函数,那么我们只要定义一个内部函数暂存下外部函数的值即可,代码如下 def count(): fs = [] for i in range(1, 4): def f(j = i): return j*j fs.append(f) return fs f1, f2, f3 = count() print(f1()) print(f2()) print(f3())
接下里再通过一个例子看看返回闭包的又一特点
例子 三
#猜猜下面代码会输出什么?复制代码在你的IDE上印证以下吧! def fun(): x = 5 def inner(): #没错!俺是闭包! nonlocal x x += 1 return x return inner #还是将闭包返回出去 small_box = fun() for i in range(1, 4): print(small_box()) #不知你猜对没有,这里就是返回闭包的一个强大功能了,因为返回的是 #闭包,所以相当于每一次都把inner()执行一遍,而非重新执行fun(), #相当于将大盒子里面的小盒子取出来,然后不断执行小盒子里面的操作, #而小盒子里面拥有的大盒子的东西会一直改变,所以输出并非三个6!
最后咱们结合第二和第三个例子构造第四个例子作为练习猜猜输出
例子 四
#猜猜下面这两段代码输出啥? def foo(): ret = [] x = 5 for i in range(1, 4): def inner(): nonlocal x return x x += 1 ret.append(inner) return ret L = foo() for fun in L: print(fun()) #----------华丽分割-------------- def foo(): ret = [] x = 5 for i in range(1, 4): def inner(): nonlocal x x += 1 return x ret.append(inner) return ret L = foo() for fun in L: print(fun()) #试着自己解释下原因
欢迎指出错误的地方,以后学到相关的还会继续补充!
以上是关于python闭包的主要内容,如果未能解决你的问题,请参考以下文章