函数装饰器

  当在多个地方,要使用相同的代码来完成一项操作的时候,可以考虑将这些代码写成一个函数,然后在不同的地方调用这个函数,就可以简化代码量。通常情况下,一般代码函数都是已经写好的,一个函数模块,就完整定义了一个功能,当需要向这个功能模块增加新的功能时,可以选择直接修改这个函数体,如果涉及到的函数特别多,这种情况下,就可以通过另一种方式来实现了,也就是装饰器。装饰器是用来在不改变原有函数的调用方式的基础上,为函数增加新的功能的方法。

  开放封闭原则:

  1. 开放:说的是为原有函数增加功能
  2. 封闭:说的是对源代码不做修改,封闭的

  在理解装饰器之前,先需要了解一下函数。函数是一段代码的集合,通过调用函数,就能执行特定的功能。函数的调用,分成两个部分,1、函数的定义,2、函数的调用。

  在函数定义的部分,编写了这个函数要执行的操作,包括函数名,参数,以及各种逻辑,函数定义的结果,就是在内存中生成一个对象。函数的调用过程,就是对象执行的过程。如果函数只是定义了没有调用,则在内存中只是生成了一个对象,当程序运行完成后,这个对象就被内存释放掉了。

def func_new():
    print("this is func_sub")
print(func_new)
func_new()

  比如上面的代码部分,先是定义了一个func_new函数,然后直接打印了这个函数对象在内存中的地址,然后调用了这个函数,打印输出。

  当要在这个函数的基础上,增加一个其他的功能,通用的功能,比如计算这个函数运行的时间的功能,在不改变原有代码的情况下添加该功能,这个时候就会用到装饰器,装饰器,实际上就是函数的嵌套,将一个函数A作为另一个函数B的参数,先执行B,后执行A的过程。函数的嵌套,前提条件是要先定义了内层函数,然后再定义外层函数,在执行的时候是先执行外层函数,再执行内层函数。

  先做一个简单的函数嵌套的函数。

def func_new():
    print("this is func_sub")

def function():
    print('this is deco func')
    func_new()

function()

  定义一个内层函数func_new,然后再顶一个外层函数function,在外层函数中调用该内层函数。定义完成后,直接调用外层函数,就能看到函数的执行。在功能比较多的时候,可以考虑将内层函数作为变量,在外层函数中直接调用。外层函数是原始功能,新增加的功能是内层函数,如果要调用的地方很多,则需要在很多地方修改函数体本身。这样做也不太好。

def function(func_sub):
    def deco(*args,**kwargs):
        print('this is deco func')
        func_sub()
    return deco()

def func_new():
    print("this is func_sub")

function(func_new)

  这种情况下,将内层函数,作为变量,传入到函数定义中,函数定义中有两层,内层函数中,是调用了功能函数,外层函数只是定义一个函数,然后调用一次。第一个函数就是新加的功能,第二个函数就是以前的原始函数。在执行这个函数的时候,是将原始函数作为参数,直接传递到新创建的函数中,执行。这种方式,虽然能实现新增加功能,但是改变了原始函数的调用方式,也不太好。

  下面就到了装饰器的时候了。先看看装饰器是怎么写的。

def function(func_sub):
    def deco(*args,**kwargs):
        print('this is deco func')
        func_sub()
    return deco
@function
def func_new():
    print("this is func_sub")

func_new()

  定义一个装饰器函数function,在function函数内,定义一个deco函数,在函数中定义了新的功能,然后调用了一个位置参数,该参数就是原始功能函数。装饰器函数,返回一个系统内存对象,也就是内层函数。原始功能func_new在调用时,先执行了装饰器函数,将原始功能函数作为装饰器函数的参数,传递进去,然后执行函数。装饰器函数的参数,是一个内存对象,返回结果也是一个内存对象。

  如果要实现相同的效果,在调用原始函数时,修改一下代码。

def function(func_sub):
    def deco(*args,**kwargs):
        print('this is deco func')
        func_sub()
    return deco()
@function
def func_new():
    print("this is func_sub")

func_new

  装饰器函数,参数是内存对象,返回值是内存对象的调用结果,也能实现一样的功能,但是改变了原始函数的调用过程。区别就在返回值上面。

  所以可以看到,装饰器函数,直接就是将原始函数作为一个内存地址对象,传递进去,然后返回内存地址对象。在原始函数调用时,实际上就是该返回值内层地址对象的执行过程。参数什么的,只要在返回的内层函数中定义参数就可以,外层的装饰器函数,只要传递进去一个函数对象在内存中的地址即可。

 

posted @ 2020-10-07 10:57  波波波波波  阅读(145)  评论(0编辑  收藏  举报