zoukankan      html  css  js  c++  java
  • 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")
    
    
    • 总体思路和实验一查不多.通过代码调试可以清晰的看到程序运行的路线.
    • 实验代码并不严谨,只是为了演示作为函数运行的占位标识
  • 相关阅读:
    Python 模块的安装与使用
    Python——list切片
    IPv4与IPv6数据报格式
    计算机网络——网络层
    大型网站技术
    mysql主从复制数据库
    Laravel-安装composer
    centos7 yum安装配置redis
    最新cenos执行service httpd restart 报错Failed to restart httpd.service: Unit not found.
    Memcache安装
  • 原文地址:https://www.cnblogs.com/ops-sylar/p/6397600.html
Copyright © 2011-2022 走看看