前言
闭包 这个概念在很多编程语言中都有,如js 等许多函数式编程语言,闭包主要是通过 函数返回函数 来实现,能保存当前函数在调用时的状态,在Python中闭包主要应用在装饰器上,装饰器在py中非常常见,特别是在一些框架中,在JAVA中也比较常见,如Spring Boot 中就用到了大量的装饰器,但是Python的装饰器和JAVA的装饰器有很大不同,但目的都是为了便于管理和加快编程效率
闭包
下面代码的f2返回给f后内存并未完全销毁,因为还有引用指向f2的一个内部函数ff2 ,ff2被暴露出来这就是闭包
f每次调用的状态都会保存
闭包有个缺点就是会浪费大量内存,因为函数不能完全释放空间,函数必须把一个内部函数返回出去,造成无法释放空间
def f2(count): def ff2(): nonlocal count count+=1 return count return ff2 f = f2(1) 下面每次调用都是之前的状态+1 #2 3 4 5 6 7 8 9 for i in range(10): print(f())
装饰器
- 下面是最简单的函数装饰器
父函数接受一个函数,内部函数将接受传递进来函数的参数
wapper(*args,**keys)
这样就可以接受无限多的位置参数以及关键字参数,然后内部函数进行装饰之后再把参数解包给传进来的函数,最后wapper会被返回出来,并赋值给f 这里的f其实就是新的wapper
def decorate(func): print("******前*******") def wapper(*args,**keys): #新的函数 f=wapper print("==========") func(*args,**keys) print("===========") print("******后*******") return wapper @decorate #执行decorate函数 会被加载到内存 并且执行函数decorate def f(a,b,c): print(a,b,c) f(1,b=2,c=99) print(f)
- 多层装饰器和参数装饰器
1、多个装饰器装饰时会依赖就近原则,靠近函数的先执行先装饰
2、 如果装饰器要传参的话需要定义三层函数
第一层传递装饰器参数
第二层传递函数
第三层传递函数的参数
# ===============多层装饰器========================= def d1(func): print("-----------------d1-------------") def w1(*args,**keys): print("====w1====") func(*args,**keys) print("====w1====") print("-----------------d1-------------") return w1 def d2(func): print("-----------------d2-------------") def w2(*args, **keys): print("====w2====") func(*args, **keys) print("====w2====") print("-----------------d2-------------") return w2 ##=================带参数装饰器============ def dd(a): #负责接收装饰器参数 print("------------dd-----------") def d(func): #负责接收函数 def wapper(*args,**kwargs): #负责接收函数参数 print("======dd=========") print("*********"+a+"******") func(*args,**kwargs) print("=======dd========") return wapper print("------------dd-----------") return d @dd("pb") @d1 @d2 def f(): print("f") f()