python帶參數裝飾器的兩種寫法
前言
最近在實現一個裝飾器的過程中發現了一個很有意思的地方,在博客里面分享出來
不同的寫法
-
三層函數嵌套,實現了可傳參數的一個裝飾器。
import logging import functools def logger(msg=None): """日志""" def dector(func): @functools.wraps(func) def wrapper(*args, **kwargs): result = func(*args, **kwargs) logging.info(func.__name__ + func.__doc__) logging.info(f"參數:{args}{kwargs}") if msg: log.info(msg.format(result)) return result return wrapper return dector
-
使用
functools.partial
函數實現了一個比較抽象的三層帶參數裝飾器。import logging import functools def loggers(func=None, msg=None): """日志""" if func is None: return functools.partial(loggers, msg=msg) @functools.wraps(func) def wrapper(*args, **kwargs): result = func(*args, **kwargs) logging.info(func.__name__ + func.__doc__) logging.info(f"參數:{args}{kwargs}") if msg: log.info(msg.format(result)) return result return wrapper
有何異同
可以看到從代碼的閱讀層面來講,第一個寫法是比較易讀的,第二種寫法不容易閱讀。從執行調用方面第二種更簡單點。
先看以下第一種調用執行的方式:
-
第一種寫法
-
裝飾器傳參數
-
裝飾器不傳參數
-
-
第二種寫法
-
裝飾器不帶參數
-
裝飾器帶參數
-
可以看到使用了functools.partial
函數的裝飾器,在調用非必填參數時,可以不用使用括號。
除了寫法理解比較抽象,這樣的調用還是比較友好的。