Python入门基础教程之装饰器(3)

从第2和第3次调用myfunc函数来看,并没有实现每次调用都返回第1次调用的效果,那么我们要实现每次调用都带有附加功能的效果,我们后面会=逐步实现。

第三步:使用@符号来装饰函数

# -*- coding:utf-8 -*-
'''示例3:使用@符号装饰函数,相当于"myfunc = deco(myfunc)",但发现新函数只在第一次被调用,且原函数多调用了一次。等价于第二步程序 '''
def deco(func):
    print ("before myfunc() called.") 
    func()
    print ("after myfunc() called.") 
    return func
   
@deco
def myfunc():
    print ("myfunc()called.")
 
myfunc()
myfunc()

#执行结果:
before myfunc() called.
myfunc()called.
after myfunc() called.
myfunc()called.
myfunc()called.

第四步:使用内嵌包装函数来确保每次新函数都被调用

# -*- coding:utf-8 -*-
'''示例4: 使用内嵌包装函数来确保每次新函数都被调用,内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''
def deco(func):
 def _deco():
    print ("before myfunc() called.")
    func()
    print ("after myfunc() called.")
 # 不需要返回func,实际上应返回原函数的返回值
 return _deco
 
@deco
def myfunc():
 print ("myfunc() called.")
 return 'ok'
 
myfunc()
myfunc()
执行结果:
before myfunc() called.
myfunc() called.
after myfunc() called.
before myfunc() called.
myfunc() called.
after myfunc() called.

上面是实现了1个函数使用装饰器的例子,下面演示2个函数分别使用装饰器的实例:

# -*- coding:utf-8 -*-
'''增加打印函数执行时间功能,分别统计两个函数的执行效率 '''
import time
def deco(func):
 def _deco():
    start_time=time.time()
    func()
    end_time=time.time()
    print("执行总耗时:",end_time-start_time)
 return _deco
 
@deco
def myfunc():
 print (" myfunc() called.")
 time.sleep(1)
 return 'true' 

@deco
def youyfunc():
 print (" youyfunc() called.")
 time.sleep(2)
 return 'true'
 
myfunc()     
print ('*'*20)
youyfunc()

#结果:
#myfunc() called.
#执行总耗时: 1.0080790519714355
#********************
# youyfunc() called.
#执行总耗时: 2.0119848251342773

#执行过程解析:
 执行myfunc()等价于执行deco(myfunc)()
#首先myfunc函数作为参数传递给了deco()函数,形参func被替换为实参myfunc,deco()函数开始顺序执行_deco()函数,
#先调用了myfunc()函数,开始执行myfunc函数,打印执行总耗时,最后返回_deco()函数对象。

说明:使用装饰器的函数之间变量不会互相影响,等于每次调用都会重新生成一个_deco函数。
第五步:实现对带参数的函数进行装饰

# -*- coding:utf-8 -*-
'''  内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象 '''
def deco(func):                                 
  def _deco(a, b):                               
        print ("before myfunc() called.")             
        ret = func(a, b)                                                                       
        print ("after myfunc() called. result: %s" % ret)
        return ret                                     
  return _deco 
                                 
@deco                                           
def myfunc(a, b):                               
  print ("myfunc(%s,%s) called."%(a, b))       
  return a + b
                                   
myfunc(1, 2)  #使用print (myfunc(1, 2)) 查看return ret 的结果                               
myfunc(3, 4) 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/04cbdde677d5a3a4504d7488d7ac80df.html