zoukankan      html  css  js  c++  java
  • day17 装饰器(上)

    一、什么是装饰器

    装饰:是对其他已有的事物添加额外具有一定意义的事物

    器:是一种工具,在程序内可以定义成函数

    合到一起就是:

    ​ 装饰器就是一个函数,为了给其他函数添加额外的功能

    二、为什么要有装饰器

    这里要引入一个设计程序的一个概念:开放封闭原则

    开放:指的是对扩展功能是开放的,就是指原来设计的功能是可装饰的

    封闭:指的是对修改源代码是封闭的,原来代码的某一个功能可能在不同场景有多种不同的应用,一旦修改会造成连锁反应。为此,一般情况下上线的功能不做源代码的修改

    装饰器就是在不修改被装饰对象的

    三、无参装饰器的使用

    需求:不修改index函数的源代码,以及调用方式的前提下加统计函数运行时间的功能

    def index(x,y):
        print(x,y)
        return 123
    res = index(1,2)
    print(res)
    >>>1,2
    >>>123
    

    第一步:我们先要回忆函数的开放封闭原则,不能对函数源代码修改,我们只能在函数外修改

    import time
    start = time.time()
    def index(x,y):
        print(x,y)
        return 123
    stop = time.time()
    print(stop - start)
    res = index(1,2)
    print(res)
    >>>0.0007340908050537
    >>>1,2
    >>>123
    

    第二步:这里我们已经实现了不修改index源码也不修改参数调用方式的情况下添加新功能了但是这样写的局限性很高,我们只对当前位置的函数index进行了装饰,当然在整个程序里index不可能只调用一次,如果对每个地方都修改就很麻烦。所以我们应该想到,把装饰器写成函数

    import time
    def index(x, y):
        print(x, y)
        return 123
    def outter(*args,**kwargs):
        start = time.time()
        res = index(*args,*kwargs)
        stop = time.time()
        print(stop - start)
        return res
    res = outter(1,2)
    print(res)
    >>>1,2
    >>>0.0007340908050537
    >>>123
    

    第三步:这里我们看起来是节省了重复代码,可以直接用outter来当更新过的index,但是我们会发现我们这个outter被写死了,我们这个装饰器只能为index函数工作,这是不符合常理的,所以我们应该把它关于index的值作为变量重新传,但是我们outter的参数已经不能修改了必须是*,**,所以这里就用到了闭包函数的应用

    import time
    def index(x,y):
        print(f"index{x},{y}")
        return 123
    
    def name(your_name):
        print(f"your name:{your_name}")
        return 456
    
    def timmer(func):
        def outter(*args,**kwargs):
            start = time.time()
            res = func(*args,**kwargs)
            stop = time.time()
            print(stop - start)
            return res
        return outter
    index = timmer(index)
    res = index(1,2)
    print(res)
    
    >>>1,2
    >>>0.0007340908050537
    >>>123
    
    name = timmer(name)
    res = name("hz")
    print(res)
    
    >>>your name:hz
    >>>0.0008175373077393
    >>>456
    

    最后一步:为了程序员编写程序的方便,引入了语法糖的概念,语法糖就是,在编译结果不便的情况下,让代码更加简洁优美。此处语法糖的应用项待遇代替了装饰器调用的代码

    import time
    
    def timmer(func):
        def outter(*args,**kwargs):
            start = time.time()
            res = func(*args,**kwargs)
            stop = time.time()
            print(stop - start)
            return res
        return outter
    #如果此处有多个装饰器,按照从下到上的顺序装饰
    @timmer 
    #@timmer相当于 index=timmer(index)
    def index(x,y):
        print(f"index{x},{y}")
        return 123
    
    @timmer 
    #@timmer相当于 name=timmer(name)
    def name(your_name):
        print(f"your name:{your_name}")
        time.sleep(1)
        return 456
    
    res = index(1,2)
    print(res)
    
    >>>1,2
    >>>0.0007340908050537
    >>>123
    
    res = name("hz")
    print(res)
    
    >>>your name:hz
    >>>0.0008175373077393
    >>>456
    
  • 相关阅读:
    oracle多表关联删除的两种方法
    T100——汇总错误消息显示
    T100——程序从标准签出客制后注意r.c和r.l
    本地DataGrip连接阿里云MySQL
    mysql for mac 上的安装及用DataGrip连接
    mac 上安装vue模版-D2 Admin
    Python 3.7版本关于json.dump失效
    设置第三方的SMTP服务
    Apache 配置代理服务
    PyCharm 通过Github和Git上管理代码
  • 原文地址:https://www.cnblogs.com/hz2lxt/p/12552377.html
Copyright © 2011-2022 走看看