龙空技术网

Python高级第六天(闭包)

黎霸天 205

前言:

此刻朋友们对“python闭合函数”可能比较着重,姐妹们都想要学习一些“python闭合函数”的相关资讯。那么小编同时在网络上汇集了一些关于“python闭合函数””的相关内容,希望大家能喜欢,各位老铁们一起来学习一下吧!

点赞加关注加转发是您给我更新的动力,如需今日相关资料或者问题可私信“资料”,特别提醒本人不是培训机构,只是爱好,自学多年分享经验,谢谢。

先看一段代码:

运行结果:

此时,内部函数对外部函数作⽤域⾥变量的引⽤(⾮全局变量),则称内部函数为闭包。这里闭包需要有三个条件。

三个条件,缺一不可:

1)必须有一个内嵌函数(函数里定义的函数)——这对应函数之间的嵌套;

2)内嵌函数必须引用一个定义在闭合范围内(外部函数里)的变量——内部函数引用外部变量;

3)外部函数必须返回内嵌函数——必须返回那个内部函数。

当一个函数在本地作用域找不到变量申明时会向外层函数寻找,这在函数闭包中很常见。

但是在本地作用域中使用的变量后,还想对此变量进行更改赋值就会报错。

报错信息:

如果我在函数内加一行nonlocal count就可解决这个问题。

代码演示:

nonlocal声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量。

如果从另一个角度来看我们给此函数增加了记录函数状态的功能。当然,这也可以通过申明全局变量来实现增加函数状态的功能。当然这样会出现以下问题:

1. 每次调用函数时,都得在全局作用域申明变量。别人调用函数时还得查看函数内部代码。

2. 当函数在多个地方被调用并且同时记录着很多状态时,就会造成非常地混乱。

使用nonlocal的好处是,在为函数添加状态时不用额外地添加全局变量,因此可以大量地调用此函数并同时记录着多个函数状态,每个函数都是独立、独特的。针对此项功能其实还有一个方法,就是使用类,通过定义__call__ 可实现在一个实例上直接像函数一样调用。

代码如下:

运行结果为:

从这段代码中,函数line与变量a,b构成闭包。在创建闭包的时候,我们通过line_conf的参数a,b说明了这两个变量的取值,这样,我们就确定了函数的最终形式(y = x + 1和y = 4x + 5)。我们只需要变换参数a,b,就可以获得不同的直线表达函数。由此,我们可以看到,闭包也具有提⾼代码可复⽤性的作⽤。如果没有闭包,我们需要每次创建函数的时候同时说明a,b,x。这样,我们就需要更多的参数传递,也减少了代码的可移植性。

1.闭包是优化了变量,原来需要类对象完成的⼯作,闭包也可以完成。

2.由于闭包引⽤了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存。

但是还没有结束,我们知道,函数内部函数,引用外部函数参数或值,进行内部函数运算执行,并不是完全返回一个函数,也有可能是一个在外部函数的值,我们还需要知道返回的函数不会立刻执行,而是直到调用了函数才会执行。

看代码:

这里创建了一个fun_a函数,外部函数的参数fun_list定义了一个列表,在进行遍历,循环函数fun_b,引用外部变量i 计算返回结果,加入列表,每次循环,都创建了一个新的函数,然后,把创建的3个函数都返回了。

但是实际结果并不是我们想要的1,4,9,而是9,9,9,这是为什么呢?

这是因为,返回的函数引用了变量 i ,但不是立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了3,每一个独立的函数引用的对象是相同的变量,但是返回的值时候,3个函数都返回时,此时值已经完整了运算,并存储,当调用函数,产生值不会达成想要的,返回函数不要引用任何循环变量,或者将来会发生变化的变量,但是如果一定需要尼,如何修改这个函数尼?

可以再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变,那我们就可以完成下面的代码

标签: #python闭合函数