詳解Python實現(xiàn)同時支持帶調(diào)用和不調(diào)用帶裝飾器
一般來說,不帶參數(shù)裝飾器,再使用時不加括號,帶參數(shù)的裝飾器使用時必須加括號。例如
- 不帶參裝飾器
def info(func): # 裝飾器,參數(shù)接收一個函數(shù),返回一個函數(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 # 使用時不加括號 def add(a, b): return a + b
- 帶參數(shù)的裝飾器(返回裝飾器的函數(shù))
def info(show_result=True): def _info(func): # 裝飾器,參數(shù)接收一個函數(shù),返回一個函數(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} 耗時: {time.time()-start_time}') return result return wrapper # 返回替換后的新函數(shù) return _info @info() # 即使使用默認參數(shù)也必須加括號調(diào)用(因為調(diào)用后才能得到裝飾器) def add(a, b): return a + b
注意: 帶參數(shù)裝飾器雖然通過參數(shù)支持定制,但是使用時必須加括號,用戶很容易遺漏或分不清是否需要加括號
能不能像@pytest.fixture那樣,既可以不帶參數(shù),也可以帶參數(shù)使用呢,例如:
import pytest @pytest.fixture def a(): ... @pytest.fixture() def b(): ... @pytest.fixture(scope='module') def c(): ...
這就要求,我們裝飾器外部函數(shù),即可以本身作為一個裝飾器(接收一個原函數(shù),返回一個同功能函數(shù)),也可以根據(jù)參數(shù)調(diào)用后返回一個裝飾器,實現(xiàn)如下:
def info(func=None, show_result=False): # 第一個參數(shù)為函數(shù) def _info(func): # 裝飾器,參數(shù)接收一個函數(shù),返回一個函數(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} 耗時: {time.time()-start_time}') return result return wrapper # 返回替換后的新函數(shù) if func is not None: # 不帶括號(作為裝飾器)使用時 return _info(func) # 返回 同功能函數(shù)wrapper(即_info的調(diào)用結(jié)果) return _info # 否則,帶括號調(diào)用(作為返回裝飾器的函數(shù))使用時,返回裝飾器 _info @info # 即使使用默認參數(shù)也必須加括號調(diào)用(因為調(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()不能手動指定第一個參數(shù)func=...
2. 在指定參數(shù)時,只能按key=value形式給出
到此這篇關(guān)于Python實現(xiàn)同時支持帶調(diào)用和不調(diào)用帶裝飾器的文章就介紹到這了,更多相關(guān)python帶調(diào)用和不調(diào)用帶裝飾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Python中4種超參自動優(yōu)化算法的實現(xiàn)
要想模型效果好,每個算法工程師都應該了解的流行超參數(shù)調(diào)優(yōu)技術(shù)。今天給大家總結(jié)超參自動優(yōu)化方法:網(wǎng)格搜索、隨機搜索、貝葉斯優(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模塊及實現(xiàn)端口轉(zhuǎn)發(fā)的例子
asyncore模塊是封裝過的處理socket事件的模塊,采用異步的處理方式,這里我們講來講解Python的Asyncore異步Socket模塊及實現(xiàn)端口轉(zhuǎn)發(fā)的例子,需要的朋友可以參考下2016-06-06