闭包



函数基本概念


  1. 函数在程序中也被看成一个对象处理
  2. 函数名就是这个对象的引用
  3. 函数引用即可以进行赋值,也可以被当做另外一个函数的参数或返回值进行传递和返回


闭包

闭包就是一种函数内部另定了另外一个函数的形式,定义闭包要满足三个条件


  1. 一个函数中定义了一个另外一个函数
  2. 内函数里运用了外函数的临时变量
  3. 外函数的返回值是内函数的引用


闭包的作用


  1. 隐藏内部函数的实现细节
  2. 代码更加安全


nonlocal


  1. 在闭包中,如果内函数只是简单使用了外函数的变量,可以不做修饰
  2. 如果对外函数的变量引用做了修改,那么要使用nonlocal 进行声明



装饰器




装饰器的是语法糖的一种

使用类或闭包来实现装饰器


装饰器的功能

在已有函数功能基础上,为已有函数添加额外的功能


装饰的使用

@xxx


装饰器的原理

      如有定义如下:

             @wrapper

             def show():

                  pass

装饰器展开的原理为:

      show = wrapper(show)


万能装饰器


  1. 根据被装饰的函数定义类型不同,装饰器的闭包定义形式可以有四种不同的变形
  2. 为了使装饰器的闭包函数更加通用,利用可变参数和关键字参数实现通用装饰器


       def setFunc(func):

            def wrapper(*args, **kwargs):   # 接收不同的参数

               print('wrapper context')

               return func(*args, *kwargs) # 再原样传回给被装饰的函数

        return wrapper



类装饰器

1.通过 __init__方法和 __call__方法,利用仿函数的特性实现类装饰器


             classTest(object):

            # 通过初始化方法,将要被装饰的函数传进来并记录下来

            def__init__(self, func):

               self.__func= func

            # 重写 __call__ 方法来实现装饰内容

            def__call__(self, *args, **kwargs):

               print('wrapper context')

               return self.__func(*args, **kwargs)

2.被类实现的装饰器进行装饰后,被装饰的函数引用指向了装饰器类的对象。

执行函数时,实际是在时行对像的仿函数形式调用


多个装饰器装饰一个函数


  1. 一个装饰器可以装饰多个函数
  2. 一个函数也可以被多个装饰器进行装饰
  3. 在装饰器装饰函数时,装饰的过程是自下向上进行装饰的。


装饰器传参


  1. 装饰器在使用过程中,可能需要对装饰器进行传参
  2. 在定义可以传参的装饰器闭包时,需要定义三层函数
  3. 最外层函数用来接收装饰器的参数
  4. 中间层用来实现装饰器
  5. 最内层用来执行具体的装饰内容
  6. 无论有几层或者几个装饰器去装饰已有函数,最终函数都是引用装饰器的最内层的函数。
  7. @xxx(xxx)  先执行传参xxx(xxx) ,实际就是执行函数调用,得到中间层函数, 与@组合后变成装饰器形式,再进行装饰