1.学习装饰器之前先了解下高阶函数
1.1:一个函数可以作为参数传给另外一个函数,或者一个函数的返回值为另外一个函数(若返回值为该函数本身,则为递归),满足其一则为高阶函数。
1.2:由此我们学习到了一个知识点:函数的返回值可以为另外一个函数;我们继续往下延伸学习:可以在一个函数中(我们简称它为外函数)定义另一个函数(我们简称它为内函数),且当内函数引用外函数的参数或变量,外函数的返回值为内函数时,这时外函数的相关参数和变量都会保留在了内函数(这也就意味着在外函数的生命周期结束后,外函数的变量依然存在因为它被内函数引用了,所以不会被回收),这种就称为“闭包”。
闭包知识点:
-
内函数中修改外函数的值
一般在函数结束时,会释放临时变量,但在闭包中,由于外函数的临时变量在内函数中用到,此时外函数会把临时变量与内函数绑定到一起,这样虽然外函数结束了,但调用内函数时依旧能够使用临时变量,即闭包外层的参数可以在内存中进行保留,如果想要在内函数中修改外函数的值,需要使用 nonlocal 关键字声明变量
def func(a, b):
def line(x):
nonlocal a
a = a+1
return a * x - b
return line
line = func(2, 3)
print(line(5)) # 12
2.还有一点需要注意:使用闭包的过程中,一旦外函数被调用一次返回了内函数的引用,虽然每次调用内函数,是开启一个函数执行过后消亡,但是闭包变量实际上只有一份,每次开启内函数都在使用同一份闭包变量。
def outer(x):
def inner(y):
nonlocal x
x+=y
return x
return inner
a = outer(10)
print(a(1)) # >>>11
print(a(3)) # >>>14
两次分别打印出11和14,由此可见,每次调用inner的时候,使用的闭包变量x实际上是同一个。
3.在 闭包中,返回函数不要引用任何循环变量,或者后续会发生变化的变量。
def count():
l = []
for i in range(1, 4):
def f():
return i*i
l.append(f)
return l # [f,f,f] 函数list
f1, f2, f3 = count()
print(f1(),f2(),f3()) #>>> 9 9 9 为什么都是9呢?思考下吧~
打印出来的结果为9,因为该函数引用了循环变量后,并非立刻执行,等到3个函数都返回时,它们所引用的变量x已经变成了3,因此最终结果为9
-------------------------------------------------------------------------------------
感兴趣的话可以关注下本人公众号哈,大家一起学习~~旁边是刘阿童木的公众号也是干货满满大家关注一波~