-
闭包函数用的知识点
-
闭包函数内容讲解
-
闭包函数作用
-
闭包函数的应用
一,闭包函数用的知识点
闭包函数需要用到名称空间和作用域+函数对象+函数嵌套,这些知识点如果并不是很清楚的话,建议可以去了解一下,这样能帮助你更好的理解下面的讲解。
二,闭包函数内容讲解
如果在一个函数的内部定义了另一个函数,外部的我们叫他外函数,内部的我们叫他内函数。
闭包:在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。
一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。
那么上代码!!!
def func(a):
b = 10
def f():
print(a+b)
return f # 这里注意,并不能返回f(),这里需要返回的是func内部函数f的引用
res= func(10)
# 到这一步的时候函数体func已经执行完了,但是其中的b的值并没有直接的释放
res() # 执行结果为 20
上面的代码是比较典型的闭包函数,但是可能一些概念什么的并不是很清楚,那么下面进行部分的讲解。
def func(a):
b = 10
def f():
print(a+b)
return f # 这里注意,并不能返回f(),这里需要返回的是func内部函数f的引用
这段代码中,为什么说这里需要返回的是 f 而非 f()?因为,我们知道函数名在内存中的存储就是函数体的内存地址,那么既然是数据就可以当作变量来使用,这里直接返回的是函数f 的内存地址,通过一个变量名res来接收返回值,但是如果我们返回的是f()的话,就导致返回给res的值是None,(也就是函数 f 的执行结果)并不是内存地址,也就无法实现在全局名称空间中直接调用函数f。这就是对名称空间的应用和函数的嵌套。
res= func(10)
# 到这一步的时候函数体func已经执行完了,但是其中的b的值并没有直接的释放
res() # 执行的结果为20
这样能直接执行函数f,但是也可以直接这样来执行,结果是相同的。
res= func(10)() # 执行结果为20
# 到这一步的时候函数体func已经执行完了,但是其中的b的值并没有直接的释放
这就是对函数对象的应用。
三,闭包函数的作用
讲了这么多,那么这个闭包函数的作用是什么呢?难道就只是这样的?那还不如我直接这样来使用不也一样?
b = 10
def f(a):
print(a+b)
f(10)
既然有闭包函数的存在,那么必然是有它存在的作用,存在即合理。那接下来就来讲解一下闭包函数的作用。
我们知道,当我们开始设计函数,然后给函数传参的时候是设计好形参和实参的,那么闭包函数就为我们提供了第二种传参解决方案。
方案一,直接通过形参,实参进行传参
def func(x):
print(x)
func(111)
执行结果就不必多说了,看都能看出来。这是很常规的设计有参函数的方式,但是如果碰上了需要传递参数的函数,但是结果函数并不需要传递参数的情况呢?同时还不想其他函数体调用该参数,这种情况该怎么处理呢?所以闭包函数为我们提供了第二种传参方案。
方案二,通过闭包函数
def func(x):
b = 10
def f2():
print(x + b)
return f2
f2 = func(1111)
print(f2)
f2()
想看执行结果的小伙伴可以复制代码,然后自己执行一遍看看,这里就不放出来看了。
讲到这里基本上就讲完了闭包函数了,但是可能还是存在疑惑,讲了这么久,还是没有看出来闭包函数的作用啊,闭包函数到底有什么用呢?
四,闭包函数的应用
其实在装饰器中,我们封装函数,但是在装饰器中并不是所用的函数都是有参函数和无参函数,但是有些时候有需要我们去向函数中传递参数,那么这个时候就可以用到了闭包函数。如果还没有接触到装饰器的小猿们,就可以简单的知道,闭包函数为我们传递参数提供了第二种方案。其实闭包函数的功能还是很强大的。可以多练习掌握一下,毕竟技多不压身。