1、引入场景:
检查代码的运行时间
import time def func(): start = time.time() time.sleep(0.12) print('看看我运行了多长时间!') end = time.time() print('此段代码运行时长为:%s'%(end - start)) func()
如果有大量的函数要检查,这样加入代码太费功夫!考虑提取为一个函数,要检查时直接调用即可
def check_time(f): start = time.time() time.sleep(0.12) f() end = time.time() print('此段代码运行时长为:%s' % (end - start)) check_time(func)
还是有问题,有人嫌每次都去调用该函数很麻烦!能不能,在不修改要测试远行时长的函数的调用方式前提下,还想在原来的函数前后添加测试时长功能?
def timing(f): # 装饰器函数 def inner(): start = time.time() time.sleep(0.12) f() # 被装饰函数 end = time.time() print('此段代码运行时长为:%s' % (end - start)) return inner func = timing(func) func()
这里就可以定义装饰器函数了,用来装饰其他函数,添加相关功能的函数叫装饰器函数
2、语法糖的使用
@timing # @装饰器函数名 相当于前面函数调用前的赋值:func_to = timing(func_to) def func_to(): # 被装饰的函数 a = 1000000 b = 1223434 return a * b func_to()
3、装饰器的作用
不想修改函数的调用方式 但是还想在原来的函数前后添加功能
上面的例子中timmer就是一个装饰器函数,只是对一个函数 有一些装饰作用
4、装饰带参数的函数
def timing_arg(f): def inner(a): start = time.time() re = f(a) end = time.time() print('此段代码运行时长为:%s' % (end - start)) return re return inner @timing_arg def func_have_arg(a): result = a * 10000000 return result
5、装饰带可变参数的函数
1 def wrapper(f): # 装饰器函数,f是被装饰的函数 2 def inner(*args, **kwargs): 3 '''在被装饰函数之前要做的事''' 4 ret = f(*args, **kwargs) # 被装饰的函数 5 '''在被装饰函数之后要做的事''' 6 return ret 7 8 return inner 9 10 @wrapper # 语法糖 @装饰器函数名 11 def func_101(a, b): # 被装饰的函数 12 time.sleep(0.01) 13 print('老板好同事好大家好', a, b) 14 return '新年好' 15 16 print(func_101(100, b=200))
6、编程原则: 开放封闭原则#
开放 : 对扩展是开放的
封闭 : 对修改是封闭的