Python裝飾器詳解
裝飾器本質(zhì)就是函數(shù),作用是裝飾其它函數(shù),給其它函數(shù)增加附加功能,提高代碼復(fù)用,減少代碼量。
我們平時給函數(shù)增加新的功能時,通過修改此函數(shù)或在函數(shù)里調(diào)用新的函數(shù)實現(xiàn),但是1、如果這個函數(shù)已經(jīng)是上線的功能,這時修改程序原代碼有很大風(fēng)險? 2、如果有100個這樣的函數(shù),我們就要找到100個地方進行修改。
例如:我們想新增功能,驗證函數(shù)執(zhí)行了多長時間,代碼如下:
#修改原函數(shù)import timedef sum1():start = time.clock()sum = 1+2print(sum)end = time.clock()print("time used:",end - start)sum1()"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.py3time used: 2.9439962316848234e-05Process finished with exit code 0#原函數(shù)內(nèi)調(diào)用新功能的函數(shù)import timedef sum1():sum = 1+ 2print (sum)def timeit(func):start = time.clock()func()end =time.clock()print("time used:", end - start)timeit(sum1)"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.py3time used: 3.071996067845033e-05Process finished with exit code 0
裝飾器原則:
1、不能修改被裝飾函數(shù)的源代碼
2、不能修改被裝飾函數(shù)的調(diào)用方式
實現(xiàn)裝飾器儲備知識:
高階函數(shù)+嵌套函數(shù)=裝飾器
1、函數(shù)即變量
def test1():print('hello!')return test1test2=test1test2()print(test2)"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.pyhello!0x0000018E5D1A8F28 >Process finished with exit code 0
2、高階函數(shù)
a:把一個函數(shù)名當(dāng)做實參傳給另外一個函數(shù)(在不修改被裝飾函數(shù)源代碼的情況下為其添加功能)
b:返回值中包含函數(shù)名
滿足a或b就是高階函數(shù)
def bar():print('in the bar')def test1(func):print(func)func()return test1test1(bar) #bar的內(nèi)存地址+調(diào)用bar函數(shù)print(test1)#test1的內(nèi)存地址print(test1(bar))#bar的內(nèi)存地址+調(diào)用bar函數(shù)+test1的內(nèi)存地址"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.py0x0000026AC7C58F28 >in the bar0x0000026AC82C89D8 >0x0000026AC7C58F28 >in the bar0x0000026AC82C89D8 >Process finished with exit code 0import timedef bar():time.sleep(3)print('in the bar')def test1(func):start_time=time.time()func()stop_time=time.time()print('the func run time is %s'%(stop_time-start_time))return funcbar=test1(bar)bar()"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.pyin the barthe func run time is 3.0008511543273926in the barProcess?finished?with?exit?code?0
3、嵌套函數(shù)
def foo():print('in the foo')def bar():print('in the bar')bar()foo()"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.pyin the fooin the barProcess finished with exit code 0
不帶參數(shù)的裝飾器:
import timedef timer(func):def deco():start_time=time.time()func()stop_time=time.time()print('the func run time is %s'%(stop_time-start_time))return decodef test1():time.sleep(3)print('in the test1')test1()"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.pyin the test1the func run time is 3.000833511352539Process finished with exit code 0
帶參數(shù)的裝飾器:
從實:1中看出@timer相當(dāng)于test2=timer(test2),timer(func)中func傳的是test2,故func=test2
timer(test2)=deco,因為test2=timer(test2),故test2=deco=func
test2(name,age)=deco(name,age)=func(name,age)所以傳參到deco和func里
實例1:import timedef timer(func):def deco(*args,**kwargs):start_time=time.time()func(*args,**kwargs)stop_time=time.time()print('the func run time is %s'%(stop_time-start_time))return decodef test1():time.sleep(3)print('in the test1')test1()def test2(name,age):time.sleep(3)print('%s %s in the test2'%(name,age))test2('wangli',22)"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.pyin the test1the func run time is 3.0001492500305176wangli 22 in the test2the func run time is 3.000540256500244Process finished with exit code 0實例2:import timedef timmer(flag):""":param flag: 接收裝飾器的參數(shù):return:"""def outer_wrapper(func):""":param func: 接收被裝飾的函數(shù):return:"""# 接收被裝飾函數(shù)的參數(shù)def wrapper(*args, **kwargs):""":param args: 收集被裝飾函數(shù)的參數(shù):param kwargs: 收集被裝飾函數(shù)的關(guān)鍵字參數(shù):return:"""if flag == "true":start_time = time.time()# 調(diào)用被裝飾的函數(shù)result = func(*args, **kwargs)# 讓進程睡一秒time.sleep(1)stop_time = time.time()print("{func} spend {time} ".format(func="add", time=stop_time - start_time))return resultelse:print("Unexpected ending")return wrapperreturn outer_wrapper
評論
圖片
表情
