第十一天 18/5/11 装饰器

一、什么是装饰器?

装饰器本质上就是一个 python 函数,它可以让其他函数在不需要做出任何代码变动的前提下,额外增加功能,装饰器的返回值也是一个函数对象。

应用场景:插入日志,性能测试,事务处理,缓存等场景。

二、装饰器的形成过程。

我有一需求,我想让你测试这个函数的执行时间,在不改变这个代码的情况下

第十一天 18/5/11   装饰器第十一天 18/5/11   装饰器
def login():
    print('游戏开始')
import time                        # 导入时间模块
start_time = time.time()    # 记录开始时间
login()                               # 开始函数
end_time = time.time()     # 记录终止时间
print('此函数所用时间为%s' % (end_time - start_time))

游戏开始
此函数所用时间为0.0
第一版本【不是函数,雏形】第十一天 18/5/11   装饰器第十一天 18/5/11   装饰器
import time                 # 导入时间模块
def login():
    time.sleep(0.3)             # 停顿时间0.3
    print('游戏开始')

def timmer():
    start_time = time.time()  # 记录开始时间
    login()                    # 开始函数
    end_time = time.time()     # 记录终止时间
    print('此函数所用时间为%s' % (end_time - start_time))
timmer()
装饰器 1.0 版

但是,如果有多个函数,我都想让你进行测试他们的执行时间,这 1.0 版是不是都得做出改变呢?

第十一天 18/5/11   装饰器第十一天 18/5/11   装饰器
import time                 # 导入时间模块
def login():                #  第一函数
    time.sleep(0.3)             # 停顿时间0.3
    print('游戏开始')
def dier():                 #   第二函数
    time.sleep(0.4)
    print('准备好了么')
def timmer(f):
    start_time = time.time()  # 记录开始时间
    f()                    # 开始函数
    end_time = time.time()     # 记录终止时间
    print('此函数所用时间为%s' % (end_time - start_time))
timmer(login)
timmer(dier)    # 改变了我原来执行函数的执行方式
1.1 版【改变了我原来执行函数的执行方式 】第十一天 18/5/11   装饰器第十一天 18/5/11   装饰器
import time                 # 导入时间模块
def login():                #  第一函数
    time.sleep(0.3)             # 停顿时间0.3
    print('游戏开始')
def timmer(f):
    start_time = time.time()  # 记录开始时间
    f()                    # 开始函数
    end_time = time.time()     # 记录终止时间
    print('此函数所用时间为%s' % (end_time - start_time))
f1 = login                     #  设变量 f1 将login 赋值给 f1
login = timmer                 #  【新设】变量 login  将 timmer 赋值给 login
login(f1)                       #  timmer(login)
1.2版,虽然还原了函数的执行方式,但增加了变量第十一天 18/5/11   装饰器第十一天 18/5/11   装饰器
import time                 # 导入时间模块
def login():                #  第一函数
    time.sleep(0.3)             # 停顿时间0.3
    print('游戏开始')
def timmer(f):
    def inner():
        start_time = time.time()  # 记录开始时间
        f()                    # 开始函数   login
        end_time = time.time()     # 记录终止时间
        print('此函数所用时间为%s' % (end_time - start_time))
    return inner
login = timmer(login)     # login = inner
login()                     # 执行函数 inner()
1.3版 利用赋值进行改变

在python中有个更简单的方法:语法糖:F1 = X1(F1)——> @X1

第十一天 18/5/11   装饰器第十一天 18/5/11   装饰器
import time                 # 导入时间模块
def timmer(f):
    def inner():
        start_time = time.time()  # 记录开始时间
        f()                    # 开始函数   login
        end_time = time.time()     # 记录终止时间
        print('此函数所用时间为%s' % (end_time - start_time))
    return inner
@timmer                     #  login = timmer(login)
def login():                #  第一函数
    time.sleep(0.3)             # 停顿时间0.3
    print('游戏开始')
login()                 # 执行函数 inner()
语法糖版

刚刚我们讨论的装饰器都是装饰不带参数的函数,现在要装饰一个带参数的函数怎么办呢?

第十一天 18/5/11   装饰器第十一天 18/5/11   装饰器
def func(x,y):
    # func (x,y)实质上是 x = 5,y = 9
    print(x,y)  # 打印 x = 5, y = 9
func(y = 9, x = 5)
补充知识点:形参=实参第十一天 18/5/11   装饰器第十一天 18/5/11   装饰器
import time                 # 导入时间模块
def timmer(f):
    def inner(x,y):
        start_time = time.time()  # 记录开始时间
        f(x,y)                    # 开始函数   login(a,b)
        end_time = time.time()     # 记录终止时间
        print('此函数所用时间为%s' % (end_time - start_time))
    return inner
@timmer                     #  login = timmer(login)
def login(a,b):                #  第一函数
    print(a,b)                  #  打印参数
    time.sleep(0.3)             # 停顿时间0.3
    print('游戏开始')
login(8,9)                 # 执行函数 inner(x,y)
装饰带参数的函数【但是有局限性,无法满足参数的灵活性】第十一天 18/5/11   装饰器第十一天 18/5/11   装饰器
import time                 # 导入时间模块
def timmer(f):
    def inner(*args,**kwargs):
        start_time = time.time()  # 记录开始时间
        f(*args,**kwargs)                    # 开始函数   login(a,b)
        end_time = time.time()     # 记录终止时间
        print('此函数所用时间为%s' % (end_time - start_time))
    return inner
@timmer                     #  login = timmer(login)
def login(*args,**kwargs):                #  第一函数
    print(args,kwargs)                  #  打印参数
    time.sleep(0)             # 停顿时间0.3
    print('游戏开始')
@timmer
def dier(*args,**kwargs):                 #   第二函数
    print(args, kwargs)
    time.sleep(0.4)
    print('准备好了么')
login(99,88,77,66,55)                 # 执行函数 inner(x,y)
dier(999,520,0,126)
#  为什么,我输给login 的数值能准确无误的送到 login 呢 这涉及到 * 的打散和重聚
更换为 动态参数

我想让函数带返回值

第十一天 18/5/11   装饰器第十一天 18/5/11   装饰器
import time                 # 导入时间模块
def timmer(f):
    def inner(*args,**kwargs):
        start_time = time.time()  # 记录开始时间
        ret = f(*args,**kwargs)     # 开始函数   login(a,b)  将返回值666赋值给 ret
        end_time = time.time()     # 记录终止时间
        print('此函数所用时间为%s' % (end_time - start_time))
        return ret              # 将返回值666 返回给 inner(*args,**kwargs)
    return inner
@timmer                     #  login = timmer(login)
def login(*args,**kwargs):                #  第一函数
    print(args,kwargs)                  #  打印参数
    time.sleep(0)             # 停顿时间0.3
    print('游戏开始')
    return 666                  # 返回值666 ,返回给 f(*args,**kwargs)
@timmer
def dier(*args,**kwargs):                 #   第二函数
    print(args, kwargs)
    time.sleep(0.4)
    print('准备好了么')
print(login(99,88,77,66,55))        # 执行函数 inner(x,y) 打印 login(99,88,77,66,55) 得到返回值
dier(999,520,0,126)
万能装饰器 模板

相关推荐