前言

闭包 这个概念在很多编程语言中都有,如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()