欢迎来到簟纹灯影的博客

人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。

装饰器知识梳理

装饰器知识梳理

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

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

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

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才是那个真正的装饰器,外层的可以理解为带参数的判断条件而已。

posted @ 2019-08-12 20:56  簟纹灯影  阅读(121)  评论(0编辑  收藏  举报