python基础-装饰器

    1、什么是装饰器

        装饰指的是为被装饰对象添加新的功能

        器指的是工具

      装饰器本身可以任意可调用的对象,被装饰的对象也可以是任意可调用的对象

    2、为什么要装饰器

        扩展新功能:写一个函数用来为另外一个函数添加新功能,需要遵循开放封闭原则(对修改是封闭的,对扩展是开放的)

        1、不修改被装饰对象的源代码

        2、不修改装饰对象的调用方式

    3、怎么用

      例如:统计函数的时间

        

      1.创建新功能(计算时间)的函数

      

      满足了第一个要求,不改变源代码。但调用方式改了

      2.创建装饰器,将新函数设计成闭包函数,被调用函数以参数形式传入装饰器
      

      3.变量接受装饰器的返回值

      

       

      虽然满足了2个要求,但只适应于 无参的被装饰函数.

      若被装饰函数为
      

      按照原来设计,则出错。闭包函数wrapper无参数

      

      所以为闭包函数添加参数*args,**kwargs

      

      最后填好返回值

      

    4.语法糖

      装饰器的语法糖:在被装饰对象的正上方单独一行写上@装饰器名字、

      就会将语法糖正下方的函数对象当做参数交给装饰器。执行后得到的返回值再交给被装饰对象

      

     5,   多个装饰器的执行顺序

      如图:

      

      解释语法自下而上。

      

      1.先将最原始函数index 当做第一个被装饰对象交给outter装饰器

      2.装饰器返回inner 闭包函数,并赋值给变量index

       即

        新的index = inner闭包函数。

      3.将新的index函数  当做第二个被装饰对象交给timmer装饰器

      4.装饰器返回wrapper闭包函数,并赋值给 变量index

       即

        最新的index = wrapper闭包函数

      总结: 

        先运行outter装饰器的闭包函数inner 的代码

        最后运行timmer装饰器的闭包函数 wrapper的代码

      

      运行图:

        

       执行是自上而下

      ◔疑问:为什么执行自上而下

         添加时间打印函数

         

         第一种情况:时间统计装饰器在上

         打印的时间是包含outter装饰器。

         

         第二种情况:时间统计装饰器timmer在下

         打印的时间未包含outter装饰器

         

       6、有参装饰器(第三层装饰器)

          为什么要有参装饰器

          如图:

         

           新需求:再添加一个信息保存的功能,根据不同的引擎保存信息。

         即需要添加一个新参数

          1、装饰器outter 不能再接受其它参数(除func外)

         

         因为outter装饰器是将index 被装饰对象当做参数。无第二个参数,也不能再添加

         

         2、闭包函数inner也不能再添加任何参数。*arg 和 **kwarg是传递给 被装饰对象的参数。 闭包函数inner 一般只做传递

         

         所以,在装饰器outter上再套一层装饰器

         

         运行

         

      

          装饰器最多三层。

         三层装饰器:

           1,第二层装饰器参数仅是   被装饰对象 的形参

           2,最内层的闭包函数的参数  仅仅提供  数据传递作用, 传递给 被装饰对象

           3,最外层的装饰器的参数可以有多个,提供给内部所有函数使用。

         

原文地址:https://www.cnblogs.com/linbin7/p/10586287.html