然后給大家介紹的是Wrapper(裝飾器),使用廣泛。python筆試,面試的話也會百分百問到的,基礎和中級的知識儲備還是必用的。
讓我們開始。
先來一些基礎相關知識
*args,**kwargs的區別 def function(x,y,*args,**kwargs): print(type(x)) print(args) print(kwargs) print(type(args)) print(type(kwargs)) function(1,2,3,4,5,a=1,b=2,c=3) <type 'int'> (3, 4, 5) #*args返回的是數組
{'a': 1, 'c': 3, 'b': 2} #**kwargs返回的字典
<type 'tuple'>
<type 'dict'>
正題開始
固定模板
裝飾器:wrapper 模板: def 裝飾器名(func): #def 與 @之后的函數名稱一致 調用函數func與ret=func(*args,**kwargs)內部函數一致
def wrapper(*args,**kwargs): #def 與 return 之后的函數名稱一致
ret = func(*args,**kwargs) return ret #return ret 與 ret=func(*args,**kwargs)一致
return wrapper @裝飾器名 def foo(): pass
import time def timmer(fun1): def wrapper(*args,**kwargs): start_time=time.time() res=fun1(*args,**kwargs) stop_time=time.time() print('run time is %s' %(stop_time-start_time)) return res return wrapper @timmer def foo(): time.sleep(3) print('from foo') @timmer def foo1(): time.sleep(5) print('from foo1') foo() foo1()
@wraps:避免被裝飾函數自身的信息丟失
未添加@wraps
#-*- coding:utf-8 -*-
def decorator(func): def inner_function(): pass
return inner_function @decorator def func(): pass
print(func.__name__) #inner_function
添加@wraps
from functools import wraps def decorator(func): @wraps(func) def inner_function(): pass
return inner_function @decorator def func(): pass
print(func.__name__) #func #@wraps:避免被裝飾函數自身的信息丟失
多個裝飾器的同時使用
def makebold(f): return lambda:'<b>'+f()+'</b>'
def makeitalic(f): return lambda:'<i>'+f()+'</i>'
def makeitalic1(f): return lambda:'<strong>'+f()+'</strong>' @makebold @makeitalic1 @makeitalic def say(): return 'hello'
print(say()) #<b><strong><i>hello</i></strong></b> #多個裝飾器的執行順序:是從近到遠依次執行。
類裝飾器
#類裝飾器
class Decorator(object): def __init__(self, f): self.f = f def __call__(self): print("decorator start") self.f() print("decorator end") @Decorator def func(): print("func") func() ''' decorator start func decorator end '''
import time def decorator(func): def wrapper(*args,**kwargs): start_time = time.time() func(*args,**kwargs) end_time = time.time() print(end_time - start_time) return wrapper class Method(object): @decorator def func(self): time.sleep(0.8) p1 = Method() p1.func() # 函數調用
''' 0.815999984741 對於類方法來說,都會有一個默認的參數self,它實際表示的是類的一個實例,所以在裝飾器的內部函數wrapper也要傳入一個參數 - me_instance(任意參數)就表示將類的實例p1傳給wrapper,其他的用法都和函數裝飾器相同。 '''
較為復雜的多個裝飾器
import time def deco01(func): def wrapper(*args, **kwargs): print("this is deco01") startTime = time.time() func(*args, **kwargs) endTime = time.time() msecs = (endTime - startTime)*1000
print("time is %d ms" %msecs) print("deco01 end here") return wrapper def deco02(func): def wrapper(*args, **kwargs): print("this is deco02") func(*args, **kwargs) print("deco02 end here") return wrapper @deco01 @deco02 def func(a,b): print("hello,here is a func for add :") time.sleep(1) print("result is %d" %(a+b)) if __name__ == '__main__': f = func f(3,4) ''' this is deco01 this is deco02 hello,here is a func for add : result is 7 deco02 end here time is 1032 ms deco01 end here '''
#多個裝飾器執行的順序就是從最后一個裝飾器開始,執行到第一個裝飾器,再執行函數本身。