• 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")
    
    
    • 总体思路和实验一查不多.通过代码调试可以清晰的看到程序运行的路线.
    • 实验代码并不严谨,只是为了演示作为函数运行的占位标识
  • 相关阅读:
    spring读取配置文件内容并自动注入
    xshell免费下载安装使用
    cas sso原理
    sql两列相除,保留n位小数
    mysql 报zone什么的错误
    mysql union出错: "Every derived table must have its own alias"
    mysql jdbc操作
    sql 对某列取值进行if判断
    Python深入:02浅拷贝深拷贝
    Python基础:22__slots__类属性
  • 原文地址:https://www.cnblogs.com/ops-sylar/p/6397600.html
Copyright © 2020-2023  润新知