Python进阶-多重嵌套和闭包

这个概念真的有点难,我思考了两天才开始写这篇教程,这和java 真的有点不太一样,没事,咱一步一步来,一点点分解。

以下内容仅作者理解,并不权威,如果有不恰当的地方,请技术大牛指点。

在python中 函数属于‘一等公民’,可以相互嵌套。

看一个例子:

Python进阶-多重嵌套和闭包_第1张图片
注意:定义内函数后,要返回内函数的引用 即 return inner

这个例子很浅显易懂,只是函数进行了嵌套

接下来看一个稍微复杂一点的例子

这里就存在一个闭包的概念,我们先看一下:

Python进阶-多重嵌套和闭包_第2张图片

闭包:在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。

#在一个外函数(outer)中定义了一个内函数(inner),内函数里运用了外函数的临时变量(x,y=10),并且外函数的返回值是内函数的引用(return inner())。这样就构成了一个闭包。

这里特殊说明一下,按照我们通常的经验,一个函数被调用的时候,会在内存空间分配一部分空间,来存储在和函数内部的变量等,当这个函数调用完成之后,这一部分空间会被释放。但是闭包有一点点不同,当外层函数执行完后,内层函数没有,它的引用依然被持有,所以外层函数的局部变量不能被释放,这个局部变量就被绑定在内层函数上了,然后外层函数再被释放。

Python进阶-多重嵌套和闭包_第3张图片
巩固一下这个解释

这里有一个错误 return inner 不能加()差别小伙伴们自己想清楚哦


20190531补充

这个东西还是要讲一下,不然讲下一个话题,不太好开展

关于inner() 和inner

inner 其实通俗的理解他就是一个函数的名字,这个名字指向一个函数,当后面没有小括号的时候,它可以被传递,被赋值,但是不会去执行。

inner()加上(),就是告诉程序,通过inner 名字找到这个函数,然后执行这个函数


通俗的讲,如何能形成闭包?

1.存在函数的嵌套2.内层函数要引用外层函数的变量3外层函数要返回内层函数的引用

为什么要使用闭包?

举个例子,这个例子是从别人那里偷来的

定义直线 y = a*x+b  如何使用闭包 创建一个函数可以生成对于任意a,b的直线呢?


Python进阶-多重嵌套和闭包_第4张图片
这样可以对于任意a,b,如果要取到任意ab 写函数 ,那要写无数个方法了

在上述代码中,内部函数line() 中其实没有临时参数a,b.在python 中如果在自己的作用于里没有找到相应的参数,即像上一级控件中去寻找,在外部函数line_fun 中找到使用

如果我们想处理 过坐标(0,1)这一点的所有直线 显然是y = a*x +1 这样一条直线,如果想像刚才一样来一个方法 大家感受一下

Python进阶-多重嵌套和闭包_第5张图片
这里看 我们并没有成功的改变b 

之所以没有改变b,就是刚才所说的作用域的问题,内部函数在内部没有找到参数b,去外层函数寻找 寻找后使用外层函数的b = 1;可以打印一下两个b的地址发现两个b 根本不是同一个b

Python进阶-多重嵌套和闭包_第6张图片
两个b 参数之间的关系

为什么?(这也是为什么叫闭包)

闭包作为对象被返回时,它的引用变量就已经确定(已经保存在它的__closure__属性中),不会再被修改。是的,闭包在被返回时,它的所有变量就已经固定,形成了一个封闭的对象,这个对象包含了其引用的所有外部、内部变量和表达式。闭包的参数例外。

print(line_fun(10).__closure__)

# (< cell at 0x10a07cb58: int object at 0x109e366c0 >, < cell at 0x10a07cb88: int object at 0x109e365a0 >)

# __closure__属性返回的是一个元组对象,包含了闭包引用的外部变量。

闭包的实际应用?

暂时还木有用到 用到后过来添加

你可能感兴趣的:(Python进阶-多重嵌套和闭包)