装饰器是Python非常重要的高级特性之一。装饰器的威力在于无需修改已有代码即可为程序添加新功能。
装饰器如何使用,首先我们来看一个例子。
例子一:用装饰器实现计算一个函数的执行时间。
#!/usr/bin/env python
import time
def calcTime(func):
def wrapper(num):
startTime = time.time()
func(num)
endTime = time.time()
interval = endTime - startTime
print('Time interval:%f secs' % intarval)
return wrapper
@calcTime
def timeTest(num):
print('timeTest start')
print('sleep %d second...' % num)
time.sleep(num)
print('timeTest end')
timeTest(1)
执行结果:
timeTest start
sleep 1 second...
timeTest end
Time interval:1.001107 secs
说明:
timeTest()
有参数时,可将装饰器的内嵌函数wrapper
修改为被装饰函数的形式即可。此时,timeTest(1)
相当于calcTime(timeTest(1))
假设想要使用共同的装饰器来修饰多个不同的函数, 则这些不同的函数参数形式不同,装饰器可以通过可变参数 (* args, **kwargs)
的方式实现内嵌函数。
那么,对于装饰器本真带参数的情况,这里举一个例子。
例子二:为装饰器添加一个bool变量,通过变量的真假判断是否调用计时器功能。
#!/usr/bin/env python
import time
def calcTime(flag = False):
if flag:
def _calcTime(func):
def wrapper(num):
startTime = time.time()
func(num)
endTime = time.time()
interval = endTime - startTime
print('Time interval:%f secs' % interval)
return wrapper
else:
def _calcTime(func):
return func
return _calcTime
@calcTime(False)
def timeTest1():
print('timeTest1 start')
print('sleep 1 second...')
time.sleep(1)
print('timeTest1 end')
@calcTime(True)
def timeTest2(num):
print('timeTest2 start')
print('sleep %d second...' % num)
time.sleep(num)
print('timeTest2 end')
timeTest1()
print()
timeTest2(2)
执行结果:
timeTest1 start
sleep 1 second...
timeTest1 end
timeTest2 start
sleep 2 second...
timeTest2 end
Time interval:2.002649 secs
说明:
如果使用多个装饰器修饰同一函数时,装饰器的调用顺序怎样呢?
例子三:
#!usr/bin/env python
def dec1(func):
print('dec1')
def wrapper():
print('dec1_wrapper')
func()
return wrapper
def dec2(func):
print('dec2')
def wrapper():
print(dec2_wrapper)
func()
return wrapper
@dec1
@dec2
def testFunc():
print('testFunc')
testFunc()
执行结果:
dec2
dec1
dec1_wrapper
dec2_wrapper
testFunc
说明:
参考:- 《物联网Python开发实战》 |
---|