一. 装饰器是什么?
简单来说,装饰器其实也就是一个函数,一个用来包装函数的函数,返回一个修改之后的函数对象,将其重新赋值原来的标识符,并永久丧失对原始函数对象的访问。
二.装饰器语法
(1)无参数装饰器
1 def deco(func): 2 print (func) 3 return func 4 @deco 5 def foo(): 6 pass 7 foo()
第一个函数deco是装饰函数,它的参数就是被装饰的函数对象。我们可以在deco函数内对传入的函数对象做一番“装饰”,然后返回这个对象(记住一定要返回 ,不然外面调用foo的地方将会无函数可用。实际上此时foo=deco(foo)
下面是一个简单的例子,检查函数有没有说明文档:
1 def deco_functionNeedDoc(func): 2 if func.__doc__ == None : 3 print (func.__name__, "has no __doc__, it's a bad habit.") 4 else: 5 print (func.__name__, ':', func.__doc__, '.') 6 return func 7 @deco_functionNeedDoc 8 def f(): 9 print ('f() Do something') 10 @deco_functionNeedDoc 11 def g(): 12 'I have a __doc__' 13 print ('g() Do something') 14 f() 15 g() 16 17 #输出如下 18 #f has no __doc__, it's a bad habit. 19 #g : I have a __doc__ . 20 #f() Do something 21 #g() Do something 22 #[Finished in 0.2s]
(2)有参数装饰器
不使用装饰器的实现代码:
import time import datetime def outter(func): def inner(args): start=datetime.datetime.now() func(args) end=datetime.datetime.now() cost=end-start print("execute %s spend %s"%(func.__name__,cost.total_seconds())) return (inner) def func2(args): time.sleep(args) f=outter(func2) f(1) #输出如下: #execute func2 spend 1.014 #[Finished in 1.2s]
使用装饰器的代码实现如下:
1 import time 2 import datetime 3 import functools 4 5 6 def outter(func): 7 @functools.wraps(func) 8 def inner(*args,**kwargs): 9 '''This is inner''' 10 start=datetime.datetime.now() 11 func(*args,**kwargs) 12 end=datetime.datetime.now() 13 cost=end-start 14 15 print("execute %s spend %s"%(func.__name__,cost.total_seconds())) 16 return (inner) 17 18 @outter 19 def func2(args): 20 '''This is func2''' 21 time.sleep(args) 22 23 @outter 24 def func3(m,n): 25 '''This is func3''' 26 print("m+n={0}".format(m+n)) 27 28 func2(1) 29 print(func2.__name__) 30 print(func2.__doc__) 31 32 func3(m=2,n=3) 33 print(func3.__name__) 34 print(func3.__doc__) 35 36 #加了@functools.wraps(func)装饰器的输出结果 37 # execute func2 spend 1.000413 38 # func2 39 # This is func2 40 # m+n=5 41 # execute func3 spend 0.0 42 # func3 43 # This is func3 44 # [Finished in 1.2s] 45 46 #不加@functools.wraps(func)装饰器的输出结果 47 48 # execute func2 spend 1.000413 49 # inner 50 # This is inner 51 # m+n=5 52 # execute func3 spend 0.0 53 # inner 54 # This is inner 55 # [Finished in 1.2s]