Python中的裝飾器用于擴(kuò)展可調(diào)用對(duì)象的功能,而無(wú)需修改其結(jié)構(gòu)。基本上,裝飾器函數(shù)包裝另一個(gè)函數(shù)以增強(qiáng)或修改其行為。我們可以通過(guò)一個(gè)具體的例子了解基礎(chǔ)知識(shí)!讓我們編寫(xiě)一個(gè)包含裝飾器實(shí)現(xiàn)示例的Python3代碼:
裝飾定義
defdecorator_func_logger(target_func):defwrapper_func():print(“Before calling”, target_func.__name__) target_func() print(“After calling”, target_func.__name__)return wrapper_funcdef target(): print(‘Python is in the decorated target function’)dec_func = decorator_func_logger(target)dec_func()Output:air-MacBook-Air:$ python DecoratorsExample.py(‘Before calling’, ‘target’)Python isin the decorated target function(‘After calling’, ‘target’)
上面的裝飾器結(jié)構(gòu)有助于我們?cè)谡{(diào)用目標(biāo)函數(shù)之前和之后在控制臺(tái)上顯示一些注釋。
以下是定義裝飾器的簡(jiǎn)單步驟;
首先,我們應(yīng)該定義一個(gè)可調(diào)用對(duì)象,例如裝飾器函數(shù),其中還包含一個(gè)包裝器函數(shù)。
裝飾器函數(shù)應(yīng)將目標(biāo)函數(shù)作為參數(shù)。
并且它應(yīng)該返回包裝函數(shù),該包裝函數(shù)擴(kuò)展了作為參數(shù)傳遞的目標(biāo)函數(shù)。
包裝函數(shù)應(yīng)包含目標(biāo)函數(shù)調(diào)用以及擴(kuò)展目標(biāo)函數(shù)行為的代碼。
defdecorator_func_logger(target_func):defwrapper_func(): print(“Before calling”, target_func.__name__) target_func() print(“After calling”, target_func.__name__)return wrapper_func@decorator_func_loggerdef target():print(‘Python is in the decorated target function’)target()Output:air-MacBook-Air:$ python DecoratorsExample.py(‘Before calling’, ‘target’)Python isin the decorated target function(‘After calling’, ‘target’)
借助Python提供的語(yǔ)法糖,我們可以簡(jiǎn)化裝飾器的定義,如上所示。
請(qǐng)注意,@ decorator_func_logger僅在我們要裝飾的目標(biāo)函數(shù)之前添加。然后,我們可以直接調(diào)用目標(biāo)函數(shù)。就像我們?cè)诘谝粋€(gè)實(shí)例中所做的那樣,無(wú)需顯式分配裝飾器。
定義多個(gè)裝飾器并使用參數(shù)裝飾函數(shù)
import timedef decorator_func_logger(target_func):defwrapper_func(*args, **kwargs):print(“Before calling”, target_func.__name__) target_func(*args, **kwargs)print(“After calling”, target_func.__name__)return wrapper_funcdef decorator_func_timeit(target_func):defwrapper_func(*args, **kwargs): ts = time.time() target_func(*args, **kwargs) te = time.time()print (target_func.__name__, (te - ts) * 1000)return wrapper_func@decorator_func_logger@decorator_func_timeitdef target(loop): count = 0 print(‘Python is in the decorated target function’)for number in range(loop): count += numbertarget(100)target(3000)Output:air-MacBook-Air:$ python DecoratorsExample.py(‘Before calling’, ‘wrapper_func’)Python isin the decorated target function(‘target’, 0.015974044799804688)(‘After calling’, ‘wrapper_func’)(‘Before calling’, ‘wrapper_func’)Python isin the decorated target function(‘target’, 0.47397613525390625)(‘After calling’, ‘wrapper_func’)
通過(guò)使用‘@’語(yǔ)法在目標(biāo)函數(shù)之前添加多個(gè)裝飾器,可以輕松地用多個(gè)裝飾器裝飾目標(biāo)函數(shù)。裝飾器的執(zhí)行順序?qū)⑴c在目標(biāo)函數(shù)之前列出的順序相同。
請(qǐng)注意,我們的目標(biāo)函數(shù)中有一個(gè)參數(shù)loop。只要包裝函數(shù)使用相同的參數(shù),就沒(méi)有問(wèn)題。為了確保裝飾器可以靈活地接受任意數(shù)量的參數(shù),將(* args,** kwargs)參數(shù)用于包裝函數(shù)。
重要要點(diǎn)
裝飾器定義可重用的代碼塊,您可以將這些代碼塊應(yīng)用于可調(diào)用對(duì)象(函數(shù),方法,類(lèi),對(duì)象),以修改或擴(kuò)展其行為,而無(wú)需修改對(duì)象本身。
請(qǐng)考慮您的腳本中有許多函數(shù)執(zhí)行許多不同的任務(wù),并且需要向所有函數(shù)添加特定的行為。在這種情況下,將相同的代碼塊復(fù)制到函數(shù)中以具有所需的功能不是一個(gè)好的解決方案。您可以簡(jiǎn)單地裝飾函數(shù)。
-
函數(shù)
+關(guān)注
關(guān)注
3文章
4307瀏覽量
62432 -
python
+關(guān)注
關(guān)注
56文章
4782瀏覽量
84456 -
調(diào)用
+關(guān)注
關(guān)注
0文章
8瀏覽量
3216
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論