裝飾器的寫法補充:
通常裝飾器的寫法是@func(),而有的時候為了減少出錯率,可能會寫成@func,沒有()括號,這時我們可以這樣定義,來減少括號。下面通過兩個例子還看。
一般裝飾器的寫法:
1 def log(func=None): 2 3 def inner(*args, **kwargs): 4 print('do something before') 5 res = func(*args, **kwargs) 6 print('do something after') 7 return rees 8 9 return inner 10 11 #使用裝飾器 12 @log() 13 def my_func(): 14 print('i am my_func') 15 16 #運行這個函數 17 my_func()
運行結果:
1 do something before 2 i am my_func 3 do something after
可以不帶括號的裝飾器寫法
需要增加判斷在函數內,用於判斷使用裝飾器的函數是否可以調用,以達到括號的自由寫法
判斷的裝飾器寫法
1 def log(func=None): 2 3 #需要再次嵌套一層裝飾器,才可以供下面運行時使用 4 def wrapper(fun) 5 def inner(*args, **kwargs): 6 print('do something before') 7 res = fun(*args, **kwargs) 8 print('do something after') 9 return rees 10 11 return inner 12 13 #判斷func(參數): 14 if func is None: 15 return wrapper 16 17 #如果func是可以調用的函數 18 elif callable(func): 19 return wrapper(func) 20 21 22 #使用裝飾器的時候,兩種寫法都可以運行 23 24 第一種不帶括號: 25 @log 26 def my_func(): 27 print('i am my_func') 28 29 第二種帶括號的: 30 @log() 31 def my_func(): 32 print('i am my_func') 33 34 35 #運行這個函數 36 my_func()
兩種方式的一樣,運行結果:
1 do something before
2 i am my_func 3 do something after
不帶括號的理解:
@log =>等同於 my_func = log(my_func)
帶括號的理解:
@log() =>等同於 my_func = log()(my_func)
結論: 內嵌之后,可以增加判斷條件,增加了裝飾器的靈活性。