詳解Python實(shí)現(xiàn)同時(shí)支持帶調(diào)用和不調(diào)用帶裝飾器
一般來說,不帶參數(shù)裝飾器,再使用時(shí)不加括號,帶參數(shù)的裝飾器使用時(shí)必須加括號。例如
- 不帶參裝飾器
def info(func): # 裝飾器,參數(shù)接收一個(gè)函數(shù),返回一個(gè)函數(shù) @functools.wraps(func) def wrapper(*args, **kwargs): # 與原函數(shù)功能一致,支持任意參數(shù) print(f'調(diào)用函數(shù): {func.__name__} 參數(shù):{args} {kwargs}') return func(*args, **kwargs) # 內(nèi)部包裹調(diào)用原函數(shù) return wrapper # 返回和原函數(shù)功能一致的函數(shù) @info # 使用時(shí)不加括號 def add(a, b): return a + b
- 帶參數(shù)的裝飾器(返回裝飾器的函數(shù))
def info(show_result=True): def _info(func): # 裝飾器,參數(shù)接收一個(gè)函數(shù),返回一個(gè)函數(shù) @functools.wraps(func) def wrapper(*args, **kwargs): # 與原函數(shù)功能一致,支持任意參數(shù) print(f'調(diào)用函數(shù): {func.__name__} 參數(shù):{args} {kwargs}') start_time = time.time() result = func(*args, **kwargs) # 內(nèi)部包裹調(diào)用原函數(shù) if show_result is True: print(f'調(diào)用結(jié)果: {result} 耗時(shí): {time.time()-start_time}') return result return wrapper # 返回替換后的新函數(shù) return _info @info() # 即使使用默認(rèn)參數(shù)也必須加括號調(diào)用(因?yàn)檎{(diào)用后才能得到裝飾器) def add(a, b): return a + b
注意: 帶參數(shù)裝飾器雖然通過參數(shù)支持定制,但是使用時(shí)必須加括號,用戶很容易遺漏或分不清是否需要加括號
能不能像@pytest.fixture那樣,既可以不帶參數(shù),也可以帶參數(shù)使用呢,例如:
import pytest @pytest.fixture def a(): ... @pytest.fixture() def b(): ... @pytest.fixture(scope='module') def c(): ...
這就要求,我們裝飾器外部函數(shù),即可以本身作為一個(gè)裝飾器(接收一個(gè)原函數(shù),返回一個(gè)同功能函數(shù)),也可以根據(jù)參數(shù)調(diào)用后返回一個(gè)裝飾器,實(shí)現(xiàn)如下:
def info(func=None, show_result=False): # 第一個(gè)參數(shù)為函數(shù) def _info(func): # 裝飾器,參數(shù)接收一個(gè)函數(shù),返回一個(gè)函數(shù) @functools.wraps(func) def wrapper(*args, **kwargs): # 與原函數(shù)功能一致,支持任意參數(shù) print(f'調(diào)用函數(shù): {func.__name__} 參數(shù):{args} {kwargs}') start_time = time.time() result = func(*args, **kwargs) # 內(nèi)部包裹調(diào)用原函數(shù) if show_result is True: print(f'調(diào)用結(jié)果: {result} 耗時(shí): {time.time()-start_time}') return result return wrapper # 返回替換后的新函數(shù) if func is not None: # 不帶括號(作為裝飾器)使用時(shí) return _info(func) # 返回 同功能函數(shù)wrapper(即_info的調(diào)用結(jié)果) return _info # 否則,帶括號調(diào)用(作為返回裝飾器的函數(shù))使用時(shí),返回裝飾器 _info @info # 即使使用默認(rèn)參數(shù)也必須加括號調(diào)用(因?yàn)檎{(diào)用后才能得到裝飾器) def add(a, b): return a + b @info() def sub(a, b): return a - b @info(show_result=True) def mul(a, b): return a * b
注意:1. 在使用裝飾器info()不能手動(dòng)指定第一個(gè)參數(shù)func=...
2. 在指定參數(shù)時(shí),只能按key=value形式給出
到此這篇關(guān)于Python實(shí)現(xiàn)同時(shí)支持帶調(diào)用和不調(diào)用帶裝飾器的文章就介紹到這了,更多相關(guān)python帶調(diào)用和不調(diào)用帶裝飾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python 實(shí)現(xiàn)二叉查找樹的示例代碼
這篇文章主要介紹了Python 實(shí)現(xiàn)二叉查找樹的示例代碼,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2020-12-12詳解Python中4種超參自動(dòng)優(yōu)化算法的實(shí)現(xiàn)
要想模型效果好,每個(gè)算法工程師都應(yīng)該了解的流行超參數(shù)調(diào)優(yōu)技術(shù)。今天給大家總結(jié)超參自動(dòng)優(yōu)化方法:網(wǎng)格搜索、隨機(jī)搜索、貝葉斯優(yōu)化?和?Hyperband,感興趣的可以了解一下2022-05-05python對輸出的奇數(shù)偶數(shù)排序?qū)嵗a
在本篇內(nèi)容里小編給大家整理的是一篇關(guān)于python對輸出的奇數(shù)偶數(shù)排序?qū)嵗a內(nèi)容,有興趣的朋友們可以參考下。2020-12-12Python的Asyncore異步Socket模塊及實(shí)現(xiàn)端口轉(zhuǎn)發(fā)的例子
asyncore模塊是封裝過的處理socket事件的模塊,采用異步的處理方式,這里我們講來講解Python的Asyncore異步Socket模塊及實(shí)現(xiàn)端口轉(zhuǎn)發(fā)的例子,需要的朋友可以參考下2016-06-06Python數(shù)據(jù)可視化探索實(shí)例分享
這篇文章主要介紹了Python數(shù)據(jù)可視化探索實(shí)例分享,數(shù)據(jù)可視化是指用圖形或表格的方式來呈現(xiàn)數(shù)據(jù),關(guān)于更多相關(guān)介紹需要的小伙伴可以參考下面文章的具體內(nèi)容2022-05-05