Python 中裝飾器加括號和不加括號的區別

在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())

這種裝飾器就比較適合複雜的需求,例如對函數進行登錄認證時,可以設置一個參數用來表示是那種認證方式等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章