在前面的文章中知道一點祸泪,變量可以指向函數(shù)酗钞,所以變量也可以調(diào)用函數(shù)
其實裝飾器的概念腹忽,就是在執(zhí)行函數(shù)外面,再套一個修飾函數(shù)砚作,用于檢查某些項是否符合窘奏。
修飾符適用于以下場景:
- 在用戶執(zhí)行某操作,操作函數(shù)一般會加上一個修飾符葫录,來判斷當前用戶是否有資格執(zhí)行【檢查條件】
- 代碼中着裹,對一個你不想改動的函數(shù),記錄函數(shù)的執(zhí)行時間米同,可以用裝飾器來搞定【記錄日志】
下面來舉個栗子看下裝飾器的使用方法:
def log(func):
def wrapper(*args, **kw):
print('call %s():'% func.__name__)
return func(*args, **kw)
return wrapper
@log
def exec_d():
print("exec_d")
然后執(zhí)行exec_d()
骇扇,得到如下結(jié)果
call exec_d():
exec_d
注意觀察下運行結(jié)果,第一行是call exec_d():
面粮,這行的打印是在log函數(shù)中執(zhí)行的少孝;第二行exec_d
是在exec_d函數(shù)中打印的
介紹下裝飾器的工作原理:
-
@log
這一行代碼,會被解釋器翻譯成log() - log()的括號內(nèi)是放著后面行的調(diào)用函數(shù)但金,在這里即
def exec_d():
韭山,所以最終解釋成log(exec_d)
通過變量是可以執(zhí)行函數(shù)的,所以log先執(zhí)行冷溃,然后在執(zhí)行exec_d函數(shù)
那如果是多個修飾符是怎么樣的執(zhí)行順序呢钱磅?試一下看看....
def log1(func):
def wrapper(*args, **kw):
print('call %s():'% func.__name__)
return func(*args, **kw)
return wrapper
def log2(func):
def wrapper(*args, **kw):
print('call %s():'% func.__name__)
return func(*args, **kw)
return wrapper
@log1
@log2
def exec_d():
print("exec_d")
exec_d()
運行結(jié)果:
call wrapper():
call exec_d():
exec_d
運行結(jié)果這里很不妙的出現(xiàn)了wrapper,因為多重裝飾器的執(zhí)行順序是log1(log2(exec_d))
似枕,log2作為一個函數(shù)盖淡,返回的是wrapper函數(shù),而不是exec_d函數(shù)凿歼,這是裝飾器的一個坑
不過可以通過導入from functools import wraps
褪迟,利用wraps返回func即可
Python3教程--傳送門