爲何要使用裝飾器呢? 裝飾器的功能:在不修改原函數及其調用方式的狀況下對原函數功能進行擴展 裝飾器的本質:就是一個閉包函數 那麼咱們先來看一個簡單的裝飾器:實現計算每一個函數的執行時間的功能bash
import time
def wrapper(func):
def inner():
start = time.time()
func()
end = time.time()
print(end - start)
return inner
def hahaha():
time.sleep(1)
print('aaaaa')
hahaha = wrapper(hahaha)
hahaha()
複製代碼
上面的功能有點不簡介,不完美,下面就引進了語法糖。閉包
import time
def wrapper(func):
def inner():
start = time.time()
func()
end = time.time()
print(end - start)
return inner
@wrapper
def kkk(): ## 至關於kkk=wrapper(kkk)
print('aaaaa')
kkk()
複製代碼
以上的裝飾器都是不帶參數的函數,如今裝飾一個帶參數的該怎麼辦呢 原函數帶多個參數的裝飾器app
import time
def timer(func):
def inner(*args,**kwargs):
start = time.time()
re = func(*args,**kwargs)
end=time.time()
print(end- start)
return re
return inner
@timer #**> func1 = timer(func1)
def func1(a,b):
print('in func1')
print(a,b)
@timer #**> func1 = timer(func1)
def func2(a):
print('in func2 and get a:%s'%(a))
return 'fun2 over'
func1(1,2)
print(func2('aaaaaa'))
複製代碼
帶返回值的裝飾器函數
import time
def timer(func):
def inner(*args,**kwargs):
start = time.time()
re = func(*args,**kwargs)
end=time.time()
print(end - start)
return re
return inner
@timer #**> func1 = timer(func1)
def jjj(a):
print('in jjj and get a:%s'%(a))
return 'fun2 over'
jjj('aaaaaa')
print(jjj('aaaaaa'))
複製代碼
1.對擴展是開放的 2.對修改是封閉的ui
import time
def wrapper(func): ## 裝飾器
def inner(*args, **kwargs):
'''函數執行以前的內容擴展'''
ret = func(*args, **kwargs)
'''函數執行以前的內容擴展'''
return ret
return inner
@wrapper ## ****=>aaa=timmer(aaa)
def aaa():
time.sleep(1)
print('fdfgdg')
aaa()
複製代碼
帶參數的裝飾器:就是給裝飾器傳參 用處: 就是當加了不少裝飾器的時候,如今突然又不想加裝飾器了,想把裝飾器給去掉了,可是那麼多的代碼,一個一個的去閒的麻煩,那麼,咱們能夠利用帶參數的裝飾器去裝飾它,這就他就像一個開關同樣,要的時候就調用了,不用的時候就去掉了。給裝飾器裏面傳個參數,那麼那個語法糖也要帶個括號。在語法糖的括號內傳參。在這裏,咱們能夠用三層嵌套,弄一個標識爲去標識。以下面的代碼示例spa
## 帶參數的裝飾器:(至關於開關)爲了給裝飾器傳參
## F=True#爲True時就把裝飾器給加上了
F=False#爲False時就把裝飾器給去掉了
def outer(flag):
def wrapper(func):
def inner(*args,**kwargs):
if flag:
print('before')
ret=func(*args,**kwargs)
print('after')
else:
ret = func(*args, **kwargs)
return ret
return inner
return wrapper
@outer(F)#@wrapper
def hahaha():
print('hahaha')
@outer(F)
def shuangwaiwai():
print('shuangwaiwai')
hahaha()
shuangwaiwai()
給裝飾器加參數
複製代碼
def qqqxing(fun):
def inner(*args,**kwargs):
print('in qqxing: before')
ret = fun(*args,**kwargs)
print('in qqxing: after')
return ret
return inner
def pipixia(fun):
def inner(*args,**kwargs):
print('in qqxing: before')
ret = fun(*args,**kwargs)
print('in qqxing: after')
return ret
return inner
@qqqxing
@pipixia
def dapangxie():
print('餓了嗎')
dapangxie()
''' @qqqxing和@pipixia的執行順序:先執行qqqxing裏面的 print('in qqxing: before'),而後跳到了pipixia裏面的 print('in qqxing: before') ret = fun(*args,**kwargs) print('in qqxing: after'),完了又回到了qqqxing裏面的 print('in qqxing: after')。因此就以下面的運行結果截圖同樣 '''
多個裝飾器裝飾一個函數
複製代碼
l=[]
def wrapper(fun):
l.append(fun)#統計當前程序中有多少個函數被裝飾了
def inner(*args,**kwargs):
## l.append(fun)#統計本次程序執行有多少個帶裝飾器的函數被調用了
ret = fun(*args,**kwargs)
return ret
return inner
@wrapper
def f1():
print('in f1')
@wrapper
def f2():
print('in f2')
@wrapper
def f3():
print('in f3')
print(l)
複製代碼