装饰器模式不用多说,记录一下python中装饰器的用法。
1,装饰器其实就是一个以函数作为参数并返回一个替换函数的可执行函数。简单的来说,就是把需要装饰的方法的外部增加一个新的功能:
import time
def deco_func(func):
start_time = time.time()
func()
end_time = time.time()
print "Total %d" % (end_time - start_time)
def __func():
print "Start!"
time.sleep(1)
print "End!"
deco_func(__func)
在这段代码中,我们将__func方法作为一个参数传到了装饰器里,增加上了统计执行时间的功能以后,就结束了,虽然勉强完成了装饰的功能,但并不完美,充其量只是利用了python 函数为对象的方式简易完成了装饰,因为执行了deco_func以后,
__func直接被执行了,而且并不是一个方法。
import time
def deco_func(func):
def wrapper():
start_time = time.time()
func()
end_time = time.time()
print "Total %d" % (end_time - start_time)
return wrapper
def __func():
print "Start!"
time.sleep(1)
print "End!"
func = deco_func(__func)
func()
在以上代码中,依然是把__func方法当做对象传入了装饰方法中,但是装饰方法中包含了一个wrapper的闭包函数,利用wrapper封装了新的功能以后,将这个方法当做参数返回,并且当其封装完成以后并没有直接被执行,而是真正执行的时候才触发了功能。
但,上面的代码还是不够完美,因为相当于我们在每一个使用__func的代码中,可能都需要写一个封装然后再调用,还是对原来的代码进行了修改。
def deco_func(func):
def wrapper():
start_time = time.time()
func()
end_time = time.time()
print "Total %d" % (end_time - start_time)
return wrapper
@deco_func
def __func():
print "Start!"
time.sleep(1)
print "End!"
这就是python中对装饰器的终极解决方案,利用了@语法糖,但@了方法以后,以后任何的
func()调用,都相当于执行了
func = deco_func(__func)
func()
接下来再贴两个带参数装饰器和不定参数装饰器的用法
固定参数
def deco_func(func):
def wrapper(a, b):
start_time = time.time()
func(a, b)
end_time = time.time()
print "Total %d" % (end_time - start_time)
return wrapper
@deco_func
def __func(a, b):
print "Start!"
# time.sleep(1)
print a + b
print "End!"
__func(1, 2)
不定参数
def deco_func(func):
def wrapper(*args, **kwargs):
start_time = time.time()
func(*args, **kwargs)
end_time = time.time()
print "Total %d" % (end_time - start_time)
# return func(*args, **kwargs)
return wrapper
@deco_func
def __func1(a, b):
print "Start!"
# time.sleep(1)
print a + b
print "End!"
@deco_func
def __func2(a):
print "Start!"
# time.sleep(1)
print a * 2
print "End!"
__func2(1)
__func1(1, 2)