網站首頁 Python教程 正文
在寫代碼的時候,往往會漏掉日志這個關鍵因素,導致功能在使用的時候出錯卻無法溯源。
其實,只需要寫一個非常簡單的日志裝飾器,我們就能大大提升排查問題的效率。
1.簡陋版裝飾器
寫一個裝飾器非常簡單,因為本質上裝飾器就是一個返回函數的“高階”函數而已:
1) 函數作為參數傳遞進裝飾器。
2) 裝飾器內定義一個函數,處理作為參數傳遞進來的函數。
3) 返回這個裝飾器內定義的函數
import datetime
def log(func):
"""
日志裝飾器,簡單記錄函數的日志
Args:
func (function): 函數
"""
def inner(*args):
timestamp = str(datetime.datetime.now()).split(".")[0]
res = func(*args)
print(f"[{timestamp}] ({func.__name__}) {args} -> {res}")
return res
return inner
用一下試試看:
@log
def pluser(a, b):
return a + b
pluser(1, 2)
效果如下:
雖然這樣可以實現我們所需要的功能,但其實有很大的優化空間。
2.普通版裝飾器
第一版代碼中有一個顯而易見的問題,裝飾器內定義的處理函數不支持kwargs,而在裝飾器中支持kwargs僅僅是舉手之勞而已。
第二個問題是,生成時間戳的時候采用字符串截取的形式,這種形式過于粗暴。其實可以使用strftime做字符串轉換。
修改如下:
import datetime
def log(func):
"""
日志裝飾器,簡單記錄函數的日志
Args:
func (function): 函數
"""
def inner(*args, **kwargs):
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
res = func(*args, **kwargs)
print(f"[{timestamp}] ({func.__name__}) {args} -> {res}")
return res
return inner
似乎優化得差不多了,不過依然存在改進空間。
3.優化版裝飾器
在前兩版代碼中,我們使用print進行日志輸出,其實這種處理日志的方式并不標準。
使用logging模塊控制日志輸出是一個更好地選擇。
為了使用logging模塊記錄日志,我們需要先配置好logging相關的選項。
1) 首先,生成一個日志記錄器,并配置日志等級:
import logging
# 獲取日志記錄器,配置日志等級
logger = logging.getLogger(__name__)
logger.setLevel('DEBUG')
2) 配置日志格式、增加handler控制輸出流:
# 默認日志格式
formatter = logging.Formatter("%(asctime)s - [%(levelname)s] - %(message)s")
# 輸出到控制臺的handler
chlr = logging.StreamHandler()
# 配置默認日志格式
chlr.setFormatter(formatter)
此處可以設置handler所需要處理的日志等級,沒有設置則默認使用logger自身的Level,即DEBUG等級。
3) 最后,將此handler加入到日志記錄器內:
# 日志記錄器增加此handler
logger.addHandler(chlr)
logging 完整配置如下:
import logging
# 獲取日志記錄器,配置日志等級
logger = logging.getLogger(__name__)
logger.setLevel('DEBUG')
# 默認日志格式
formatter = logging.Formatter("%(asctime)s - [%(levelname)s] - %(message)s")
# 輸出到控制臺的handler
chlr = logging.StreamHandler()
# 配置默認日志格式
chlr.setFormatter(formatter)
# 日志記錄器增加此handler
logger.addHandler(chlr)
使用的時候非常簡單,就是把print換成logger.debug即可:
def log(func):
"""
日志裝飾器,簡單記錄函數的日志
Args:
func (function): 函數
"""
def inner(*args, **kwargs):
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
res = func(*args, **kwargs)
logger.debug(f"func: {func.__name__} {args} -> {res}")
return res
return inner
效果如下:
這樣,一個比較完善的日志裝飾器就完成了。
附常用的日志等級配置:
原文鏈接:https://mp.weixin.qq.com/s/0lbhIAcBCjXNnh49wInYvA
相關推薦
- 2022-06-23 Android通過SeekBar調節布局背景顏色_Android
- 2022-09-26 設計模式類別,設計模式遵循的7個原則,工廠模式(靜態工廠,工廠方法,抽象工廠),7種單例模式
- 2022-04-27 關于AnacondaNavigator?Jupyter?Notebook更換Python內核的問題_
- 2022-03-16 VS2022?安裝.NET4.5目標包的方法_實用技巧
- 2022-03-03 CSS樣式修改不換行顯示省略號及多行顯示省略號
- 2022-08-04 使用systemd部署服務的過程解析_python
- 2022-09-21 Android?Flutter繪制有趣的?loading加載動畫_Android
- 2022-05-14 Centos8安裝docker報錯(錯誤提示:All?mirrors?were?tried)的問題_
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支