還在用print()查找錯誤?日誌消息這頓排骨它不香嘛?

使用日誌消息進行變量監控和程序錯誤,可以非常清晰的區分日誌消息和輸出信息,是進行程序開發時較常用的錯誤排查方法。

Hello!攢錢買生髮水的大灰狼又來了,最近在最項目開發的時候呀,跟小夥伴聊到修Bug這件事。

嗯,對於一隻沒技術的程序猿來說,修bug的確是一件讓人頭疼的事情,尤其是對於比較大型的項目開發,在變量較多的時候,一次次的檢查錯誤是真的讓頭髮顫抖。

在這裏想問一下有多少小夥伴是在Python中使用print()來輸出某個變量從而檢查參數錯誤的?

嗯…沒禿頭以前我也是這樣做的,後來我爲了以後有更多的時間去修bug,慢慢的發現斷言是個好東西,再後來爲了直接觀察到整個程序某個值的變化過程,發現還是日誌處理是真香。

在這裏插入圖片描述

那麼今天大灰狼就來和大家聊聊Python日誌處理的那些梗,

記日誌是一件很棒的事,它可以很好的幫助我們理解程序中發生的事以及事情發生的順序。

在Python中記錄程序運行的日誌文件時,我們需要調用logging模塊,通過該模塊,我們很容易的創建自定義的消息記錄,這些日誌消息將描述程序執行時,何時達到日誌函數的調用,並列出我們想要指定的任何變量當時的值。

另一方面來說呢,如果我們在日誌文件中發現某些日誌消息缺失,這就表明有一部分代碼被跳過,從未執行。這意味着什麼…嗯,我想作爲程序猿的你應該也很清楚。

1 使用日誌模塊

使用日誌消息要啓用logging模塊,在程序運行時將日誌信息顯示在屏幕上,所以我們當然需要先調用該模塊了,並且輸入以下代碼:

#調用logging函數
import logging
logging.basicConfig(filename='logginginfo.txt', level=logging.DEBUG, format=' %(asctime)s - %(levelname)s - %(message)s')

這行代碼的作用是定義的一個輸出格式,輸出某一條日誌消息執行的時間。

當python記錄一個事件的日誌時,它會創建一個LogRecord對象,保存關於該事件的信息,Logging模塊的函數讓你能夠指定看到這個LogRecord對象的細節,以及希望的細節展示方式。

值得注意的是,當我們想要將監控的值通過日誌文件進行輸出時,需要調用logging.deBug()函數,並且該函數的輸出方式與print()相同,而這行消息輸出值的格式,就是我們最開始在logging.loasicConfig()中指定的,並且包括我們傳遞給debug()的參數消息。

以一個計算階乘的函數爲例,我們監控該函數中每一個變量在程序運行時值的變化情況:

#階乘計算日誌消息輸出實例
import logging
logging.basicConfig( level=logging.DEBUG, format=' %(asctime)s - %(levelname)s - %(message)s')
#logging.disable(logging.CRITICAL)
logging.debug("程序測試:")
def factorial(n):
    logging.debug("階乘數爲:%s" %(n))
    result = 1
    for i in range(1, n + 1):
        result *= i
        logging.debug("此時乘的數爲:%s, 結果是%s" %(i, result))

    logging.debug('最終結果:%s' %(result))
    return result

print(factorial(5))

運行結果:

在這裏插入圖片描述

通過這些日誌消息的輸出,我們就可以看到在程序執行時該循環內部發生的值的變動的情況,從打印出的日誌文件可以看出,Logging.debug()函數不僅輸出了我們所監控的變量的數值,並且輸出了該函數在調用時的時間和單詞Bebug。

通過這樣的一個日誌我們就可以非常直觀的看到程序在運行過程中的變化情況。

2 不要使用print()調試程序

現在我們來聊一下,爲什麼不建議使用print()函數進行值的監控輸出,並不是說pintf函數不能夠將我們監控的變量值輸出。

而是我們在將程序調試完成的時候,需要花費很多時間從代碼中清除每條日誌消息中的print()函數,這樣的話,我們就很有可能一不小將我們期望輸出的內容進行刪除。

然而,日誌消息就很好地避免了這一點,我們可以隨心所欲的在程序中添加很多日誌變量。

那可能就會有小夥伴問了,難道使用日誌文件輸出的內容在最後就不需要禁用了嗎?

當然不是的,只是使用logging.debug()輸出的語句在最後不需要我們一個個的將其禁用,只需要調用logging.disable(logging.CRITICAL)就可以完全禁止日誌輸出。

不像print()函數那樣必須將每一行刪除或註釋掉,因此logging.disable模塊讓日誌文件的顯示和隱藏變得更加方便快捷。

哈哈,下一步你可能會認爲我要說logging.disable()函數的禁用功能了。

嗯…那接下來我們就來說一下Python中日誌消息的級別,是不是很驚喜?沒事都會有的喔!

3 日誌級別

我們所調用的日誌文件是有日誌級別的,“日誌級別”提供了一種方式。

這種方式按重要性將日誌消息進行了分類,五個日誌級別如下表所示,從最不重要到最重要,利用不同的日誌函數消息,可以按某個級別計入日誌並且輸出。

在這裏插入圖片描述

日誌消息作爲一個字符串,傳遞給這些函數,進行日誌級別的劃分只是爲了方便對程序中可能出現的錯誤的異常判斷,歸根到底,具體使用哪種級別的日誌消息,還是需要根據你的程序來定的。

日誌級別的好處就在於,我們可以改變想要看到的日誌消息的優先級,向basicConfig()函數傳入logging DEBUG作爲level的關鍵字參數,這將顯示所有日誌級別的消息。

同時在進行某項程序開發的時候我們可能並不希望顯示所有的日誌消息,這樣我們可以修改level的關鍵字參數。

例如:將basicConfig()函數的level的關鍵字參數改爲logging.ERROR,這樣將只顯示ERROR級別和CRITICAL的日誌消息,對於ERROR以下級別的日誌消息並不會顯示在屏幕上。

例如下面這行代碼,我們只禁用INFO及以下級別的日誌消息,則對於INFO以上的WARNING消息則不會禁用

#日誌禁用
import logging
logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s - %(message)s')
#禁用INFO及以下級別日誌消息
logging.disable(logging.INFO)
logging.debug("程序測試:")
def factorial(n):
    logging.debug("階乘數爲:%s" %(n))
    result = 1
    for i in range(1, n + 1):
        result *= i
        logging.debug("此時乘的數爲:%s, 結果是%s" %(i, result))

    logging.warning('最終結果:%s' %(result))
    return result

print(factorial(5))

結果如下:

在這裏插入圖片描述

好了,聊完日誌的級別,就該禁用日誌出場了!

4 禁用日誌

在調試完成以後,我們當然不希望所有這些日誌出現在屏幕之上,這時我們需要調用logging.disable函數禁用這些消息,這樣這些日誌消息就不必進入到程序之中手動刪除或者將所有日誌註釋掉,只需要向logging.disable傳入一個級別,他就會禁止該級別和更低級的所有日誌消息,

所以如果想要禁用所有日誌,只需要向程序中添加

logging.disable(logging.CRITICAL),

同時還有一點需要注意的是:logging.disable()函數將禁用他之後的所有該級別及以下的消息。

所以在這裏我們就可以將禁用日誌消息的logging.disable()函數放在程序文件的最前方,調用import logging模塊之下,這樣就很容易找到,並且根據需要來註釋掉,從而啓用或禁用日誌消息的作用。

5 將日誌記錄到文件

我們除了將日誌消息顯示在屏幕上以外,還可以將它們寫入到文本文件之中,這樣做目的是爲了我們在進行程序調試的時候,不至於很多日誌文件顯示在屏幕,從而影響我們對變量的讀取的讀取,在rogging.basicConfig函數接收filename關鍵字爲參數,像這樣:

#將日誌寫入文件
logging.basicConfig(filename='logginginfo.txt', level=logging.DEBUG, format=' %(asctime)s - %(levelname)s - %(message)s')

之後日誌消息就會被保存到某一特定的文本文件中,同樣使用求階乘的函數,將日誌消息存入txt文件中:

在這裏插入圖片描述

這樣程序輸出的結果中就只會有我們使用print()想要輸出的內容,對於日誌消息,則會保存在相應的日誌文件中去。

在這裏插入圖片描述

雖然日誌消息很有用,但如果不存入文件顯示,就可能會和我們想要輸出的結果一同顯示在屏幕上,讓我們很難找到程序中真正的輸出。將日誌信息寫入到文件以後,這樣就會使屏幕變得乾淨整潔,就能夠很好的保存信息。

這樣在程序運行之後,如果發現某些程序錯誤,我們就可以直接在該文本文件中讀取日誌,查看變量信息。

覺得不錯記得點贊關注喲!

關注我的微信公衆號 “灰狼洞主” 後臺回覆 “Python筆記” 獲取從入門到精通全套Python筆記和Python常用知識函數速查手冊!

大灰狼期待與你一同進步!

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章