python裝飾器(fuctional decorators)就是用於拓展原來函式功能的一種函式,目的是在不改變原函式名(或類名)的情況下,給函式增加新的功能。
這個函式的特殊之處在於它的返回值也是乙個函式,這個函式是內嵌「原「」函式的函式。
之前拓展函式的做法是侵入原函式進行拓展修改,例如:
原始函式:
import
time
def
f():
print
(
"hello"
)
time.sleep(
1
)
print
(
"python"
)
修改為記錄下這個函式執行的總時間,改動原來的**:
import time
def f():
begintime = time.time()
print("hello")
time.sleep(1)
print("python")
endtime = time.time()
totaltime = (endtime - begintime )*1000
print("time is %d ms" %totaltime )
使用閉包函式的用法如下:
import time
def test(func):
begintime = time.time()
f()endtime = time.time()
totaltime = (endtime - begintime) * 1000
def f():
print("hello")
time.sleep(1)
print("python")
if __name == "__main__":
test(f)
這種方式的缺點是:但是想要拓展這一千萬個函式功能,就是要執行一千萬次test()函式。
使用裝飾器來實現如下:
import time
def test(f):
def func():
begintime = time.time()
f()endtime = time.time()
totaltime = (endtime-begintime) * 1000
return func
@test
def f():
print("hello")
time.sleep(1)
print("python")
if __name == "__main__":
f()這裡的test函式就是最原始的裝飾器,它的引數是乙個函式,然後返回值也是乙個函式。其中作為引數的這個函式f()就在返回函式func()的內部執行。然後在函式f()前面加上@test,
f()函式就相當於被注入了計時功能,現在只要呼叫f(),它就已經變身為「新的功能更多」的函式了(不需要重複執行原函式)。
擴充套件1:帶有固定引數的裝飾器
import time
def test(f):
def func(a,b):
begintime = time.time()
f(a,b)
endtime = time.time()
totaltime = (endtime-begintime) * 1000
return func
@test
def f(a,b):
print("hello")
time.sleep(1)
print("python")
time.sleep(1)
print(a+b)
if __name == "__main__":
f(3,4)
擴充套件2:無固定引數的裝飾器:
import time
def test(f):
def func(*args,**kwargs):
begintime = time.time()
f(*args,**kwargs)
endtime = time.time()
totaltime = (endtime-begintime) * 1000
return func
@test
def f(a,b):
print("hello")
time.sleep(1)
print("python")
time.sleep(1)
print(a+b)
@test
def f2(a,b,c):
print("hello")
time.sleep(1)
print("python")
time.sleep(1)
print(a+b+c)
if __name == "__main__":
f(3,4)
f2(5,6,7)
擴充套件3:使用多個裝飾器裝飾乙個函式
import time
def test1(f):
def func(*args,**kwargs):
print("test1")
begintime = time.time()
f(*args,**kwargs)
endtime = time.time()
totaltime = (endtime - begintime) * 1000
print("test1 end")
return func
def test2(f):
def func(*args,**kwargs)
print("test2 begin")
f(*args,**kwargs)
print("test2 end")
return func
@test1
@test2
def f(a,b):
print("hello")
time.sleep(1)
print("python")
time.sleep(1)
print(a+b+c)
if __name__ == "__main__":
f(3,4)
執行結果:
test1
test2 begin
hello
python
7test2 end
test1 end
裝飾器呼叫順序
裝飾器是可以疊加使用的,那麼使用裝飾器以後**是啥順序呢?
對於python中的」@」語法糖,裝飾器的呼叫順序與使用 @ 語法糖宣告的順序相反。
在這個例子中,」f(3, 4) = test1(test2(f(3, 4)))」。
python內建裝飾器
Python中的裝飾器理解
主要記住兩個例子就好 1.裝飾器含有不確定引數 需要注意 1.裝飾器的引數func為函式,裝飾器內部函式 deco的引數 args,kwargs為func函式傳入的不確定性變數。2.裝飾器以輸出的函式作為形參,返回內部自定義的函式 內部自定義的函式返回形參傳入的函式 所以可認為,裝飾器傳入函式,返回...
python裝飾器理解 python裝飾器理解
裝飾器 在不改變原函式的 和呼叫方法的基礎上,給原函式增加額外的功能 理解宣告 為了方便理解,以下例子採用最簡潔的函式和新增的功能 給原函式新增乙個執行時間 import time def timer func def inner func return inner timer func timer...
python裝飾器 理解Python裝飾器
在python中,對於乙個函式,若想在其執行前後做點什麼,那麼裝飾器是再好不過的選擇,話不多說,上 usr bin env coding utf 8 script 01.py author howie from functools import wraps def decorator func wr...