python 装饰器有哪些_python之装饰器
一,什么是裝飾器?
裝飾器本質上就是一個python函數,他可以讓其他函數在不需要做任何代碼變動的前提下,增加額外的功能,裝飾器的返回值也是一個函數對象。
裝飾器的應用場景:比如插入日志,性能測試,事務處理,緩存等等場景。
二,裝飾器的形成過程。
現在我有一個需求,我想讓你測試這個函數的執行時間,在不改變這個函數代碼的情況下:
importtimedeffunc1():print('in func1')deftimer(func):definner():
start=time.time()
func()print(time.time() -start)returninner
func1=timer(func1)
func1()
裝飾器---簡單版
但是如果有多個函數,我都想讓你測試他們的執行時間,你每次是不是都得func1 = timer(func1)?這樣還是有點麻煩,因為這些函數的函數名可能是不相同,有func1,func2,graph,等等,所以更簡單的方法,python給你提供了,那就是語法糖。
importtimedeftimer(func):definner():
start=time.time()
func()print(time.time() -start)returninner
@timer#==> func1 = timer(func1)
deffunc1():print('in func1')
func1()
裝飾器---語法糖
剛剛我們討論的裝飾器都是裝飾不帶參數的函數,現在要裝飾一個帶參數的函數怎么辦呢?
deftimer(func):definner(a):
start=time.time()
func(a)print(time.time() -start)returninner
@timerdeffunc1(a):print(a)
func1(1)
裝飾器——帶參數的裝飾器
裝飾器---帶參數的裝飾器
importtimedeftimer(func):def inner(*args,**kwargs):
start=time.time()
re= func(*args,**kwargs)print(time.time() -start)returnrereturninner
@timer#==> func1 = timer(func1)
deffunc1(a,b):print('in func1')
@timer#==> func2 = timer(func2)
deffunc2(a):print('in func2 and get a:%s'%(a))return 'fun2 over'func1('aaaaaa','bbbbbb')print(func2('aaaaaa'))
裝飾器---hold住所有參數的裝飾器
上面的裝飾器已經非常完美了,但是有我們正常情況下查看函數信息的方法在此處都會失效:
defindex():'''這是一個主頁信息'''
print('from index')print(index.__doc__) #查看函數注釋的方法
print(index.__name__) #查看函數名的方法
如何解決呢?
from functools importwrapsdefdeco(func):
@wraps(func)#加在最內層函數正上方
def wrapper(*args,**kwargs):return func(*args,**kwargs)returnwrapper
@decodefindex():'''哈哈哈哈'''
print('from index')print(index.__doc__)print(index.__name__)
三,開放封閉原則。
1.對擴展是開放的
為什么要對擴展開放呢?
我們說,任何一個程序,不可能在設計之初就已經想好了所有的功能并且未來不做任何更新和修改。所以我們必須允許代碼擴展、添加新功能。
2.對修改是封閉的
為什么要對修改封閉呢?
就像我們剛剛提到的,因為我們寫的一個函數,很有可能已經交付給其他人使用了,如果這個時候我們對其進行了修改,很有可能影響其他已經在使用該函數的用戶。
裝飾器完美的遵循了這個開放封閉原則。
四,裝飾器的主要功能和固定結構。
deftimer(func):def inner(*args,**kwargs):'''執行函數之前要做的'''re= func(*args,**kwargs)'''執行函數之后要做的'''
returnrereturn inner
裝飾器的固定格式
from functools importwrapsdefdeco(func):
@wraps(func)#加在最內層函數正上方
def wrapper(*args,**kwargs):return func(*args,**kwargs)return wrapper
裝飾器的固定格式--wraps版
五,帶參數的裝飾器。
假如你有成千上萬個函數使用了一個裝飾器,現在你想把這些裝飾器都取消掉,你要怎么做?
一個一個的取消掉? 沒日沒夜忙活3天。。。
過兩天你領導想通了,再讓你加上。。。
defouter(flag):deftimer(func):def inner(*args,**kwargs):ifflag:print('''執行函數之前要做的''')
re= func(*args,**kwargs)ifflag:print('''執行函數之后要做的''')returnrereturninnerreturntimer
@outer(False)deffunc():print(111)
func()
帶參數的裝飾器
六,多個裝飾器裝飾一個函數。
defwrapper1(func):definner():print('wrapper1 ,before func')
func()print('wrapper1 ,after func')returninnerdefwrapper2(func):definner():print('wrapper2 ,before func')
func()print('wrapper2 ,after func')returninner
@wrapper2
@wrapper1deff():print('in f')
f()
多個裝飾器裝飾一個函數
總結
以上是生活随笔為你收集整理的python 装饰器有哪些_python之装饰器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python语言的重要性_【一点资讯】这
- 下一篇: websocket python爬虫_p