在一些反複使用的語句或函數的應用場景時,修改的封閉性不能很好地保證,或者不夠優雅,裝飾器解決了這一問題
例如,當我們想知道程式的運作時間時,在開始運作前擷取一個時間戳,運作結束時擷取一個時間戳,兩者做差,能夠得出程式的運作時間,需要每次調用函數時,在首尾都要添加擷取時間戳函數,之後做差,一旦修改需求,就會很麻煩,我們可以使用裝飾器
裝飾器的實質與閉包類似,其中展現了函數是一個對象,可以傳入作為參數
import time
def decorator(func):
def wrapper(*args, **kwargs):
start = time.time()
func(*args, **kwargs)
end = time.time()
print("running time:" + str(end - start))
return wrapper
def func(n):
sum = 0
for i in range(n):
sum += i
f = decorator(func)
f(10000)
裝飾器的python文法糖,讓這樣的格式變得友善,上下兩者等價
import time
def decorator(func):
def wrapper(*args, **kwargs):
start = time.time()
func(*args, **kwargs)
end = time.time()
print("running time:" + str(end - start))
return wrapper
@decorator
def func(n):
sum = 0
for i in range(n):
sum += i
func(100000)
裝飾器文法
def decorator(func):
def wrapper(*args,**kwargs):
...
func(*args,**kwargs)
return wrapper
- 将
封裝起來wrapper
- 可以用
調用,不影響原函數的調用@+裝飾器名稱
裝飾器的問題
import time
from functools import wraps
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
func(*args, **kwargs)
end = time.time()
print("running time:" + str(end - start))
return wrapper
@decorator
def func(n):
sum = 0
for i in range(n):
sum += i
func(100000)
print(func.__name__)