在Python 中使用裝飾器的時候,可能會碰到加括號裝飾和不加括號裝飾器的情況。那麼這兩種情況到底有什麼區別呢?下面分爲兩種情況來說明
第一種:必須不叫括號才能正常裝飾的寫法
import time
# 1、這種裝飾不能攜帶括號,否則沒法運行。因爲@timer() 解釋器在執行時會先執行 timer 函數,所以沒法運行
def timer(func):
def test3(*args,**kwargs):
print('查看是否攜帶參數:', args, kwargs)
start_time = time.time()
x = func(*args,**kwargs)
end_time = time.time()
print('函數執行耗時:', end_time - start_time)
print('x表示被裝飾函數的返回值:',x)
return x
return test3
@timer # 相當於 test1 = timer(test1),所以不能加括號,因爲加括號就會被解釋器 先執行timer 返回 test3,它就變成了 @tests => test1 = test3(test1),自然會報錯
def test1():
time.sleep(2)
x = 1
print('in the test1')
return x
if __name__ == '__main__':
print(test1())
這種裝飾器適合簡單的需求,也比較好維護,容易理解。
第二種:必須要加括號才能正常裝飾的寫法
import time
# 2、這種情況就必須要加括號,才能正常裝飾其他函數
def out_timer(name='測試'):
def timer(func):
def test3(*args,**kwargs):
print('查看是否攜帶參數:', args, kwargs)
start_time = time.time()
x = func(*args,**kwargs)
end_time = time.time()
print('函數執行耗時:', end_time - start_time)
print('x表示被裝飾函數的返回值:',x)
return x
return test3
return timer
# 參數可以傳遞進去做更加複雜的操作
@out_timer() # 相當於 test2 = out_timer(test2),這個時候解釋器就沒法正常進行,因爲out_timer是最外層裝飾器,需要加括號運行out_timer 返回一個裝飾器函數 timer,此時就會變爲 @timer => test2 = timer(test2)
def test2():
time.sleep(1)
x = 2
print('in the test2')
return x
if __name__ == '__main__':
print(test2())
這種裝飾器就比較適合複雜的需求,例如對函數進行登錄認證時,可以設置一個參數用來表示是那種認證方式等。