首先我們先來實現日志的功能,日志可以使用python3自帶logging模塊,不會的可以百度一下相關文章,也可以看我另外一篇文章Python3學習筆記24-logging模塊
在封裝日志類前,我們需要想一下,我們需要實現怎樣的日志功能,需要把日志放到項目下指定路徑,文件名為日期.log,需要把所有日志輸出到一個文件中,需要把報錯的日志單獨輸出到另一個文件,info和error需要不同的日志格式
那先在PyCharm里新建一個項目,在這個項目下新建一個Logs文件夾,和getcwd.py文件。然后在Logs文件下建一個Alll_Logs文件夾,Error_Logs文件夾和log.py文件。項目結構如下圖
在getcwd.py中輸入如下代碼
import os def get_cwd(): path = os.path.dirname(os.path.abspath(__file__)) #當前文件的絕對路徑 return path
這樣子是通過getcwd.py文件的絕對路徑,來獲得項目所在文件夾地址。其他一些獲取路徑的方法,會獲取當前執行文件的路徑,會導致路徑錯誤
然后在log.py文件封裝日志功能,輸入以下代碼

#-*- coding: UTF-8 -*- import logging import time import os import getcwd def get_log(logger_name): #創建一個logger logger= logging.getLogger(logger_name) logger.setLevel(logging.INFO) #設置日志存放路徑,日志文件名 #獲取本地時間,轉換為設置的格式 rq = time.strftime('%Y%m%d%H%M',time.localtime(time.time())) #設置所有日志和錯誤日志的存放路徑 path = getcwd.get_cwd() #通過getcwd.py文件的絕對路徑來拼接日志存放路徑 all_log_path = os.path.join(path,'Logs/All_Logs/') error_log_path = os.path.join(path,'Logs/Error_Logs/') #設置日志文件名 all_log_name = all_log_path + rq +'.log' error_log_name = error_log_path + rq +'.log' #創建handler #創建一個handler寫入所有日志 fh = logging.FileHandler(all_log_name) fh.setLevel(logging.INFO) #創建一個handler寫入錯誤日志 eh = logging.FileHandler(error_log_name) eh.setLevel(logging.ERROR) #創建一個handler輸出到控制台 ch = logging.StreamHandler() ch.setLevel(logging.INFO) #定義日志輸出格式 #以時間-日志器名稱-日志級別-日志內容的形式展示 all_log_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') #以時間-日志器名稱-日志級別-文件名-函數行號-錯誤內容 error_log_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(module)s - %(lineno)s - %(message)s') #將定義好的輸出形式添加到handler fh.setFormatter(all_log_formatter) ch.setFormatter(all_log_formatter) eh.setFormatter(error_log_formatter) #給logger添加handler logger.addHandler(fh) logger.addHandler(eh) logger.addHandler(ch) return logger log1 = get_log("test")
最后一行代碼是直接在日志類創建了一個實例,括號里面的test可以填項目名稱表示哪個項目,在調用日志類的時候,直接import這個log1,不用在使用的時候再去初始化,一來避免重復去初始化,二來可以避免偶爾info日志重復打印的問題
接下來測試一下日志類,隨便新建一個.py文件,輸入以下代碼
from Logs.log import log1 try: log1.info("開始測試") r = 10/0 log1.info("resuit:",r) except ZeroDivisionError as e : log1.error("報錯信息:",exc_info = 1) log1.info('end')
打印報錯信息請使用exc_info=1 這樣能把完整的報錯信息都打印出來
這是在控制台日志輸出的截圖
這是All_Logs文件夾下的日志輸出截圖
這是Error_Logs文件夾下日志輸出截圖,可以看到兩個日志文件輸出正確,輸出的格式也是對的