什么是装饰器?
- 装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码修改的提前增加额外功能。
- 装饰器的返回值也是一个函数对象。
- 装饰器的作用就是为已经存在的对象添加额外的功能。
#原函数 improt time def foo (): #原函数 print ("guo hailan") time.sleep(2) def bar():#原函数 print ("tang qinghua") time.sleep(3)
#需求,在原函数新增一个计时的功能
实例:
def foo(): start = time.time()#获取当前时间 print ("guo hailan") time.sleep(2) end = time.time() print ("spend %s"%(end - start))#计算执行用了多长时间 def bar(): start = time.time()()#获取当前时间 print ("tang qinghua") time.sleep(3) end = time.time() print ("spend %s"%(end - start) """ 函数虽然实现了功能,但是改变了原来的功能函数,如果是公共函数,修改一旦出错,影响到整个各个功能都出错。
不允许你动我的原函数,这是封闭原则,还有一个开放原则,虽然你不可以在原功能上修改,但是你可以扩展 """
新增功能,重复代码太多
这样就造成大量雷同的代码,为了减少重复写代码,我们可以这样做,重新定义一个函数,定义一个专门显示时间的函数
实例:
def show_time(): start = time.time() foo()#需要计时的函数 end = time.time() print ("spend %s"%(end - start))
"""
这个函数只能计算foo()函数的时间
如果要计算bar时间怎么办,又要重建立新的函数呢
"""
#我们将定义显示时间函数,传一个参数(传入功能函数)计算哪个函数就传入哪个函数名字。
实例:
def show_time(f): #f是传入的参数函数 start = time.time() f() #接受的函数 end = time.time() print ("spend %s"%(end - start)) show_time(foo)#调用函数 show_time(bar) """ 功能是实现了,但是调用方式改变了,之前调用的是foo(), 所有调用foo()的函数都要跟着改成show_time() 所有的业务都要跟着改,有点不合理 """
问题是怎么不改变调用方式能实现功能。我们的要求是,调用foo()就能实现原函数功能和计时功能。
我们可以对show_time(foo)赋值,做一个嵌套函数
def show_time(f): #装饰器函数 def inner(): start = time.time() f() end = time.time() print ("spend %s"%(end - start)) return inner #装饰函数返回值是一个函数对象(返回的是inner的内在地址) foo = show_time(foo) #赋值给foo (这一句要放在原有函数的下面) def foo(): print ("guo hailan") time.sleep() foo = show time(foo) foo()#执行这个的时候相当于是执行inner函数 ‘‘‘
python 提供了一个比较高大上的表示方法@show_time @show_time等价于 foo = show time(foo) @show_time 放在原功能函数的上面 ‘‘‘ 实例: @show_time() def foo(): print ("guo hailan") time.sleep() foo() #函数调用