装饰器简单指导
众所周知
装饰器能够包装函数并返回包装好的函数
在不修改函数的定义时让函数的运行发生变化
一、装饰没有参数的函数
先看看这个小明认为的rtime装饰器import time
def rtime(f):
print (time.strftime('%H:%M:%S',time.localtime(time.time())))
return f()
def pr():
print('I am pr()')
pr = rtime(pr())
虽然他起到了修改函数运行结果的作用,but我认为这不是一个装饰器
因为它直接运行了rtime之后,pr就变成了None,对程序并没有帮助。
因此,我们需要闭包,在里面加上一个func.
import time
def rtime(f):
def inner():
print (time.strftime('%H:%M:%S',time.localtime(time.time())))
return f()
return inner
def pr():
print('I am pr()')
pr = rtime(pr)
pr()
当然,还可以用@来装饰。
import time
def rtime(f):
def inner():
print (time.strftime('%H:%M:%S',time.localtime(time.time())))
return f()
return inner
@rtime
def pr():
print('I am pr()')
pr()
注意!
返回rtime得到的函数要加上()因为这是为了运行它!二、装饰有参数的函数
要是拿上面的rtime装饰器去装饰下方的mul函数,会发生什么?import time
def rtime(f):
def inner():
print (time.strftime('%H:%M:%S',time.localtime(time.time())))
return f()
return inner
@rtime
def mul(x,y):
return x*y
print(mul(1,1))
结果
Traceback (most recent call last):
File "D:\1\asasasa.py", line 11, in <module>
mul(1,2)
TypeError: inner() takes 0 positional arguments but 2 were given
异常信息指出:inner要0个参数,but他得到2个。
我们修改内部的函数。
import time
def rtime(f):
def inner(x,y):
print (time.strftime('%H:%M:%S',time.localtime(time.time())))
return f(x,y)
return inner
@rtime
def mul(x,y):
return x*y
print(mul(1,2))
结果
12:51:34
2
可是还有3,4,5,6……个参数的函数咋办?
祭出args,kwargs!
import time
def rtime(f):
def inner(*a,**b):
print (time.strftime('%H:%M:%S',time.localtime(time.time())))
return f(*a,**b)
return inner
@rtime
def mul(a,b,c,d,e,f,g):
return a*b*c*d*e*f*g
print(mul(1,2,3,4,5,6,7))
这样就解决问题了。
可是,我们想要装饰器也有参数。
三、给装饰器加参数
我们三层函数就好了。 参考log()def log(a):
def inner(f):
def Inner(*d,**b):
print('[%s]CALLING %s'%(a,f.__name__))
return f(*d,**b)
return Inner
return inner
@log('debug')
def f(a,b,c):
return a+b+c
print(f(1,2,3))