python函式的裝飾器
阿新 • • 發佈:2018-11-11
裝飾器
裝飾器的本身也是一個函式,它可以讓其他函式在不需要做任何程式碼變動的前提下,增加額外的功能,裝飾器的返回值也是一個函式物件,就是函式裝飾函式的這樣的一個過程。
裝飾器的應用場景:比如插入日誌,效能測試,事務處理,快取等等場景。
裝飾器的形成
比如,測試一個函式的執行時間,在不改變原有程式碼的情況下,實現這個功能
簡單裝飾器
import time def func1(): print('this is func1') def timer(func): def inner(): start = time.time() func() print(time.time() - start) return inner func1 = timer(func1) func1()
但是這樣還是有一個不好的地方,就是隻要我們要實現這個功能,就有有這樣一句話func1 = timer(func1),這樣就會有點麻煩:就產生了一個叫語法糖的東東,是什麼呢?
語法糖
import time def timer(func): def inner(): start = time.time() func() print(time.time() - start) return inner @timer #==> func1 = timer(func1) def func1(): print('in func1') func1()
帶引數的裝飾器
def timer(func):
def inner(a):
start = time.time()
func(a)
print(time.time() - start)
return inner
@timer
def func1(a):
print(a)
func1(1)
帶動態引數的裝飾器
import time def wrapper(func): def inner(*args, **kwargs): start_time = time.localtime() time_now = time.strftime("%Y-%m-%d %H:%M:%S", start_time) with open('log', encoding='utf-8', mode='a') as f1: f1.write("在%s是時間,執行了%s函式\n" % (time_now, func._name_)) ret = func(*args, **kwargs) return ret return inner() @wrapper def func1(): time.sleep(1) print(555) @wrapper def func2(): time.sleep(2) print(666) func1() func2()
檢視函式資訊的方法
def index():
'''這是一個主頁資訊'''
print('from index')
print(index.__doc__) #檢視函式註釋的方法
print(index.__name__) #檢視函式名的方法
例如:
from functools import wraps
def demo(func):
@wraps(func) #@wraps要載入最內層函式的正上方
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
@demo
def index():
'''你以為這是什麼就是個註釋而已'''
print('this is index')
print(index.__doc__)
print(index.__name__)
開放封閉的原則
裝飾器遵循開放封閉的原則
1.對擴充套件是開放的,也就是說,必須允許程式碼擴充套件、新增新功能。
2.對修改是封閉的,儘可能的如果再次修改,不會影響別人的使用。
裝飾器的主要功能和固定結構
'''裝飾器的固定結構'''
def timer(func):
def inner(*args, **kwargs):
'''執行函式之前要做的'''
re = func(*args, **kwargs):
return re
'''wraps版'''
from functools import wraps
def demo(func):
@wraps(func) #@wraps要載入最內層函式的正上方
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
帶引數的裝飾器
def outer(flag):
def timer(func):
def inner(*args, **kwargs):
if flag:
print('執行函式之前要做的')
re = func(*args, **kwargs)
if flag:
print('執行函式之後要做的')
return re
return inner
return timer
@outer(False)
def func():
print('6666')
func()
多個裝飾器裝飾一個函式
def wrapper1(func):
def inner():
print('wrappers1,before func')
func()
print('wrappers1,after func')
return inner
def wrapper2(func):
def inner():
print('wrappers2,before func')
func()
print('wrappers2,after func')
return inner
@wrapper1
@wrapper2
def f():
print('in f')
f()