Lucas

导航

装饰器(decorator)

装饰器概要

  本质:函数。

  功能:装饰其他函数,即为其他函数增加其他功能。

  原则:不修改被装饰函数的源代码;不修改被装饰函数的调用方法。

实现装饰器用到的知识:

  1.函数即“变量”

  2.高阶函数:♦把一个函数名当作实参传给另一个函数→可以实现不修改被装饰函数的源代码

        ♦返回值中包含函数名→可以实现不修改函数的调用方式

  3.嵌套函数

接下来看一个例子

import time

def test():
    time.sleep(2)
    print("lucas")
test()

 

运行结果:

lucas

Process finished with exit code 0

接下来我们采用装饰器给函数增加一个功能,看看该程序运行的时间:

import time

def timer(func): #功能:定义一个deco函数,并返回deco的地址
    def deco(*args,**kwargs):
        start_time = time.time()
        func() 
        stop_time = time.time()
        print(stop_time-start_time)
    return deco

@timer   #相当于 test = timer(test) 即把deco的地址赋给test
def test():
    time.sleep(2)
    print("lucas")
test()  #此时test和deco指向同一地址,运行deco的函数体

运行结果:

lucas
2.0001139640808105

Process finished with exit code 0

实现了无参函数的装饰器。总结一下:

其实过程就相当于我们要执行test(),变成了执行deco()。如果test中带参数,也就相当于deco中带的参数,为了程序的可移植性,我们人为将deco中的参数定为*args,**kwargs。也就是可变长的参数。接下来我们看一下test中带参数的简单实例:

import time

def timer(func): #功能:定义一个deco函数,并返回deco的地址
    def deco(*args,**kwargs):  #相当于test中的参数
        start_time = time.time()
        func(*args,**kwargs)  #相当于test中的参数
        stop_time = time.time()
        print(stop_time-start_time)
    return deco

@timer   #相当于 test = timer(test) 即把deco的地址赋给test
def test(name):
    time.sleep(2)
    print(name)
test("lucas")  #此时test和deco指向同一地址,运行deco的函数体

运行结果:

lucas
2.0001139640808105

Process finished with exit code 0

成功实现了修饰含参数的函数。

回头想一下,结合例子,只要记住如下的话:

定义timer函数,是为了保证被修饰的函数的调用方式不改变,即test调用方式不改变,仍为test()

定义deco函数,是为了保证在不改变被修饰函数(test)源代码的基础上,实现对其增加新功能(新增打印时间功能)。

 

posted on 2017-10-12 14:52  莲蓉馅的和氏璧  阅读(186)  评论(0编辑  收藏  举报