装饰器:开放封闭原则,为一个函数加上新的功能,不改变原函数,不改变调用方式
def fun2(wtf):
def fun3():
print('i am pythoner!!! ')
wtf()
return fun3
@fun2
def fun1():
print('this is fun1')
fun1()
输出:
i am pythoner!!!
this is fun1
1 def fun2(wtf): 2 def fun3(*args, **kwargs): 3 print('i am pythoner!!! ') 4 wtf(*args, **kwargs) 5 return fun3 #这里不是fun3()是因为:return作用在于函数赋值,即让fun3指向fun1的函数内存地址 6 7 @fun2 # @fun2 当于fun1 = fun2(fun1) ,把下面的函数传递到装饰器函数里面,相当于 fun1 = fun2(fun1) = fun3(用return令fun1=fun3), 后面再执行fun1() , 相当于执行fun3() 8 def fun1(arg, arg2): 9 print('this is fun1: %s %d' % (arg, arg2)) 10 fun1('tom', 55) #注意此处fun1()调用的实际是fun3(),而不是原来的fun1()了
注意:只要函数应用装饰器,函数就被重新定义,重新定义为:装饰器的内层函数
def runtime(func):
def warpper():
start_time = time.time()
func()
end_time = time.time()
print 'run time is %s' % (end_time-start_time)
return warpper
@runtime
def test1():
time.sleep(3)
print 'in the test1'
test1()
带参数的装饰器举例:
1 def outer(func): 2 def inner(a, b): 3 print('heihei') 4 r = func(a, b) #func即index函数,即inner函数 5 return r 6 return inner 7 8 9 @outer # index = outer(index) = inner 10 def index(a1, a2): 11 print('----------') 12 return a1 + a2 13 14 print(index(1, 2)) 15 16 输出: 17 heihei 18 ---------- 19 3
@outer 作用
1. 执行outer函数,将index作为参数传递
2. 将outer的返回值,重新赋值给index
3. 执行index函数时不再是原来的index函数,而是执行装饰器中的inner函数(由装饰器中的return赋值使index=inner)
带N个参数的装饰器:
应用场景:
当一个装饰器装饰多个函数时,而这些函数的参数个数都不相同时。
原理:
1 #原理: 2 def f1(*args, **kwargs): 3 print(args) 4 print(kwargs) 5 6 f1(1, 2, 3, 4, M1='123') 7 输出: 8 (1, 2, 3, 4) 9 {'M1': '123'} 10 11 dic = {'a': 2, 'b': 23333} 12 tup = (1, 2, 3) 13 f1(*tup, **dic) 14 15 输出: 16 (1, 2, 3) 17 {'a': 2, 'b': 23333}