zoukankan      html  css  js  c++  java
  • 装饰器知识梳理

    装饰器知识梳理

    首先,我们要理解装饰器的含义,顾名思义,装饰器的主要作用就是装饰!即为一个或多个现有的函数增加功能

    在了解装饰器功能前,我们先了解为什么要使用装饰器,好比某个项目已经上线,但是现在想给其中几个功能添加一点功能,这时候我们应该尽量做到不去修改原方法的代码调用方式,以这两点为要求,就出现的装饰器。

    我们先来看看装饰器的运作模式:

    def timer(func):
        def wrapper(*args,**kwargs):
            import time 
            start = time.time()
            re = func(*args,**kwargs)
            end = time.time()
            print("total time :",start-end)
            return re
        return wrapper
    
    @timer
    def index():
        print("你好,世界!")
        
    index()
    

    接下里我们进行详细的解释:

    ​ 装饰器的引用方式就是在被装饰函数上用@加上装饰器的名称

    装饰器的本质就是函数,所以这里有一个概念:

    • 高级函数+嵌套函数 = 装饰器

    装饰器的实际效果应该是:

    index = timer(index)
    index()
    

    这里说的就是高级函数的概念,函数本身是对象,它可以作为另一个函数的参数返回值,也可以赋值。所以在第一句index = timer(index)index实际接收的是timer返回的wrapper方法的地址,此时的index()实际就是wrapper()

    如果理解了这一点,那么就再去理解嵌套函数。首先,在一个函数体内定义的方法是无法被外部直接引用的。意思就是:

    def test1():
        def test2():
        	pass
        return test2
        
    test2()    #非法的,全局变量中没有test2    
    

    以上方的代码为例,函数test2是属于test1局部变量,所以无法在全局中直接调用局部变量中的某一个变量,如果想用test2只能通过test1的返回值。这就是函数之间的嵌套。

    值得注意的是,定义函数的目的就是为了执行,所以不要忘了调用方法。记得在嵌套函数里使用return

    理解以上的概念应该对装饰器有了一定的概念,装饰器就是执行传入方法增加一定的功能返回原方法的返回值函数

    顺便一提,在wrapper方法中传入*args**kwargs的目的是将被装饰函数的参数传递过来。re = func()目的是获得原方法的返回值。


    补充:多级嵌套装饰器:

    为什么会用到多级嵌套装饰器呢?比如现在有一个网站,本来用的MySQL数据库,但是现在做大做强了,一部分数据存到了oracle数据库,那么就要对以前的的功能进行修改与分类,去不同的数据库查找数据。

    所以就要在开始做一个判断:

    def auth(database):
        def login(func):
            def inner(*args,**kwargs):
                if database == 'mysql':
                    username = input("username:")
                    pwd = input("pwd:")
                    if username == 'du' and pwd == '123':
                        print("登录成功!")
                        return  func(*args,**kwargs)
                    else:
                        print("登录失败")
                elif database == 'orcle':
                    print("非法请求!")
            return inner
        return login
    
    @auth('mysql')
    def shopping():
        print("shopping")
    

    有同学会问,为什么非要在外层套一个呢?我们这样理解,实际上被装饰函数的装饰器是哪个呢?

    auth(database) 返回的是login方法,所以本质上login才是那个真正的装饰器,外层的可以理解为带参数的判断条件而已。

  • 相关阅读:
    PHP:第四章——PHP数组处理函数
    PHP:第四章——PHP数组array_intersect计算数组交集
    PHP:第四章——PHP数组array_diff计算数组差集
    PHP:第四章——PHP数组查找,替换,过滤,判断相关函数
    GPG入门
    GPG入门教程
    运行gpg --gen-key生成key时出现卡住的问题
    程序员练级攻略(2018) 与我的专栏
    构建一个在线ASCII视频流服务
    Ubuntu 16.04配置国内高速apt-get更新源
  • 原文地址:https://www.cnblogs.com/zhuangyl23/p/11354930.html
Copyright © 2011-2022 走看看