python装饰器

装饰器

python中的函数如果不添加()进行操作,会将自己的内存地址返回.装饰器就主要是利用这种原理进行工作.

实验一

原有代码如下,

 def Calc(a, b):
     if a > b:
         print("当a大于b")
         print("干a大于b的其它事情")
     elif a < b:
         print("当a小于b")
         print("干a小于b的其它事情")
     else:
         print("a等于b")

现需求如下,要求在不改变Calc函数代码和调用方式的情况下,增加对用户使用这个Calc进行一个int类型检查的功能

def inspect_Num(Orig_func):
    def wrapper(a, b):  		#wrapper函数会接收Calc()执行时获得的参数
        a = int(a)
        b = int(b)				#这里没有做字符和数字,符号的检查.主要是演示装饰器功能,代码太多容易看蒙圈
        return Orig_func(a, b)
        						#才真正的执行Calc函数.

    return wrapper

@inspect_Num     				
								#在这里@inspect_Num相当于Calc=inspect_Num(Calc),将CLac函数的内存地址当参数执行inspect_Num函数
def Calc(a, b):
    if a > b:
        print("当a大于b")
        print("干a大于b的其它事情")
    elif a < b:
        print("当a小于b")
        print("干a小于b的其它事情")
    else:
        print("a等于b")

Calc(7,5)    					
								#此时执行Calc函数实际上是将Calc当参数给inspect_Num,并将7,5作为参数传入了login_Fun函数内

  • 执行流程
  1. 将inspect_Num函数载入内存
  2. 读取 @inspect_Num 装饰器标记
  3. 执行inspect_Num函数 (因为 @inspect_Num相当于: Calc=inspect_Num(Calc))
  4. 此时inspect_Num函数将载入wrapper函数内存地址并作为返回值返回)
  5. 装饰器标记完毕
  6. 将Calc函数载入内存
  7. 执行Calc() 因为第三步的封装此时的Calc()其实是执行的wrapper()并传入参数
  8. 触发装饰器标记wrapper函数
  9. 将Calc函数内存地址作为参数传入内部
  10. 将Calc的参数7和5传入wrapper内部
  11. wrapper内部执行代码执行(由于wraper函数里有return Orig_func)
  12. 由于wraper函数里有return Orig_func() 找到真正Calc()
  13. 最后返回执行的Calc函数执行结果,

图片描述

实验二

要求在不改变Calc函数代码和调用方式的情况下,增加对功能:1,用户使用Calc前int类型检查的功能,2,在最后输出一个a和b相加的结果

def inspect_Num(a, b):                          #新增功能1,检查数据
    a = int(a)
    b = int(b)
    print("Num检查")
    return a, b
def add_Num(a, b):                              #新增功能2,加法运算
    i = a + b
    print("a + b = %s"% i )
    return i

def modify_Func(first_func, second_func):       #传入需要增加的功能函数
    def tran_Func(calc_func):                   #传入主函数
        def wrapper(a, b):                      #装饰器函数,按照条件执行新的功能函数

            first_func(a, b)                    #执行calc前的功能
            calc_func(a, b)                     #执行calc主函数
            second_func(a, b)                   #执行calc后的功能函数
            
        return wrapper
    return  tran_Func

@modify_Func(inspect_Num, add_Num)
def Calc(a, b):
    if a > b:
        print("当a大于b")
        print("干a大于b的其它事情")
    elif a < b:
        print("当a小于b")
        print("干a小于b的其它事情")
    else:
        print("a等于b")

Calc("8","9")

  • 总体思路和实验一查不多.通过代码调试可以清晰的看到程序运行的路线.
  • 实验代码并不严谨,只是为了演示作为函数运行的占位标识
原文地址:https://www.cnblogs.com/ops-sylar/p/6397600.html