python之闭包、装饰器

时间:2022-04-25 22:51:16

  一、学习Python的时候发现函数内部,还可以写函数,并且可以返回函数。觉得挺新奇的,主要是在探索装饰器(有点像Java的注解)的时候,发现这个理解还是很主要的,所以这里记录一下。

  二、闭包

  1)首先看一部分代码

def sum1(x):
    def sum2(y):
        print x + y
    return sum2

  2)理解:

  a、外部传入一个参数

  b、在sum1内部声明了一个sum2函数,并且需要传参数,但是没有调用
  c、然后返回了sum2函数

  3)执行:

sum2 = sum1(10)
sum2(2) //12
sum2(4) //14

  4)闭包:在第一次调用完成后,按理说x应该用结束了,但是内部函数还需要使用。后续计算直接使用x的变量值得出x+y的结果。

  简单一点:就是外层函数传入一个参数a, 内层函数依旧传入一个参数b, 内层函数使用a和b, 最后返回内层函数

  三、装饰器

  1)首先还是看一段代码和执行结果

def w1(fn):
    print "w1"
    def inner():
        print "in1"
        fn()
    return inner

def w2(fn):
    print "w2"
    def inner():
        print "in2"
        fn()
    return inner

@w1
@w2
def f():
    print "f"

f()

  执行结果:

  python之闭包、装饰器

  2)说明

  装饰器:这个看着其实有点像AOP的过程,在spring中存在通过AOP的方式来进行切面,然后加入其它逻辑,比如:事务等。这里的修饰器也就是,在原来的函数基础上,做了更多地工作用来包装原本函数执行结果。

  注意:Python中的装饰器和spring中的AOP还是存在差别,就是装饰器是嵌套装饰的,AOP是一层一层切面的。(感觉也差不多)

  3)理解

  a、f()通过@w2装饰,即为:w2f = w2(f()).

  注意:这里返回的是w2中的inner,是以第一次包装后的函数。

  b、通过第二次包装@w1,然后返回w1w2f = w1(w2f)

   注意:这里包装的是@w2包装后的函数

  c、执行过程:包装顺序,从下往上。

          然后执行函数,执行w1w2f-->w2f-->f

   四、通用装饰器

  不带参数装饰器:

def func(function_name):
    
    def func_in(*args, **kwargs):
        return function_name(*args, **kwargs)
    
    return func_in

   带参数的装饰器:

def func_arg(*args1, **kwargs1):

    def func(function_name):

        def func_in(*args2, **kwargs2):

            return function_name(*args2, **kwargs2)

        return func_in

    return func

   类装饰器:

class ClassArg:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        self.func(*args, **kwargs)