1 问题描述
请设计一个装饰器,它可以作用于任何函数上,打印函数执行时间
import time
def metric(fn):
start_time = time.time()
end_time = time.time()
print('耗时:{:.4f}s'.format(end_time - start_time))
return fn
2 解题提示
本题是对装饰器的练习
- 装饰器参考第二节内容 继承和多态、@property、装饰器
- 时间模块的导入 使用 import语句
- 定义两个变量用来接收函数开始的时间,结束时的时间
- 两个变量进行相减计算出函数运行的时间
- 使用f._ _name _ _ 来传递要测量时间的函数的函数名
3 评分标准
- 本题共计30分,实现装饰器20分
- 输出函数执行的时间 5分
- 代码注释、格式5分
4 要点解析
4.1 * 与 ** 参数
动态参数的表示,有时候我们要传入参数的数目不确定,这时候就需要用到动态参数。主要作用,就是扩展函数的功能
- *代表要把传入的参数转为一个元组,
- **代表要把传入的参数转为一个字典。
def func_1(*args):
print (args)
func_1(1,2,3,4,5,[1,3,5,7])
# 输出:(1, 2, 3, 4, 5, [1, 3, 5, 7])
def func_2(**kwargs):
print (kwargs)
func_2(k1=1,k2=2,k3=3)
# 输出:{'k1': 1, 'k2': 2, 'k3': 3}
def fun_3(arg,*args,**kwargs):
print(arg,args,kwargs)
fun_3(6,7,8,9,a=1, b=2, c=3)
# 输出:6 (7, 8, 9) {'a': 1, 'b': 2, 'c': 3}
4.2 推导式与三元表达式
# 将奇数取出,作为一个新的列表
# 一般方式
lst = [1,2,3,4,5,6,7,8]
new_lst = []
for i in lst:
if i %2==1:
new_lst.append(i)
print(new_lst)
# 推导式
lst = [1,2,3,4,5,6,7,8]
new_lst = [i for i in lst if i%2==1]
print(new_lst)
# 三元表达式
a=7
b=7
a=a-2 if a>6 else 2
print(a)
b=b-2 if a>8 else 2 # 如果满足条件,b=b-2,不满足 输出 else后面的
print(b)
4.3 装饰器概念
- 定义:python装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能
- 应用场景:引入日志,函数执行时间的统计,执行函数前的准备工作,执行函数后的处理工作,权限校验,缓存等
- 语法规则:在原有的函数上加上 @符,装饰器会把下面的函数当作参数传递到装饰器中,@符又被成为 语法糖
def m(n):# 装饰函数
print(n)#现在的形参n==被装饰的函数
def nb():# 被装饰
print('***************')#我在传入的函数执行之前做一些操作
n()# 执行函数
print('***************')#我在目标函数执行后再做一些事情'
return nb#【1】返回nb函数名
# 自动将其下面的函数作为参数传到装饰函数中去
@m
# 被装饰函数
def ych():
print('装饰器')
ych()
4.4 带参装饰器
def m(n):# 装饰函数
def nb(a):# 被装饰
print('***************')#我在传入的函数执行之前做一些操作
n(a)# 执行函数
print('***************')#我在目标函数执行后再做一些事情'
return nb#【1】返回nb函数名
# 自动将其下面的函数作为参数传到装饰函数中去
@m
# 被装饰函数
def ych(name):
print('今天是{}的生日'.format(name))
ych('zs')
def ych(name,age):
print('今天是{}的{}岁生日'.format(name,age))
ych('ls',18)
4.5 双层装饰器
def m(n):
def nb(c):
print('***************')
n(c)
print('***************')
return nb
def k(n):
def nb(c):
print('###############')
n(c)
print('###############')
return nb
@k
@m
def ych(name):
print(name,'开演唱会')
ych('刘德华')
5 代码实现
# 导入时间模块
import time
# 装饰函数
def computer_runtime(func):
# 把run方法扩展功能之后的新方法
def wrapper(*args,**kwargs):
# 函数开始时间
start = time.time()
# 调用函数
func()
# 结束时间
end = time.time()
print('%s执行了%f 秒' % (func.__name__, end - start))
# 回调装饰函数
return wrapper
#语法糖
@computer_runtime
# 被装饰函数
def run():
time.sleep(1)
l = [x**2 for x in range(1000)]
run()