Python进阶-III 函数装饰器(Wrapper)

时间:2021-12-02 16:15:44

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、装饰带可变参数的函数

 def wrapper(f):  # 装饰器函数,f是被装饰的函数
def inner(*args, **kwargs):
'''在被装饰函数之前要做的事'''
ret = f(*args, **kwargs) # 被装饰的函数
'''在被装饰函数之后要做的事'''
return ret return inner @wrapper # 语法糖 @装饰器函数名
def func_101(a, b): # 被装饰的函数
time.sleep(0.01)
print('老板好同事好大家好', a, b)
return '新年好' print(func_101(100, b=200))

6、编程原则: 开放封闭原则#
  开放 : 对扩展是开放的
  封闭 : 对修改是封闭的