
debug
前言
在沒有學(xué) logging 日志模塊之前
為了發(fā)現(xiàn)腳本程序中的的bug,通常會(huì)用下面幾種辦法來調(diào)試,檢查變量值,或者捕獲到一些難以察覺的錯(cuò)誤
print()
raise Exception()
try:
raise Exception()
except Exception as err:
- assert 表達(dá)式, "message"
實(shí)例
- 實(shí)例代碼功能,計(jì)算“數(shù)的階乘”;
#!python3
def factorial(n):
total = 1
for i in range(n + 1):
total *= i
return total
print('7! = ' + str(factorial(7)))
但是代碼中存在的問題是 range(n+1),由于 range 函數(shù),迭代生成 0 ~ n 的一組數(shù)
一開始 i 被賦值為 0,total * i 就等于零,會(huì)導(dǎo)致最終結(jié)果等于零,這顯然是不正確的
正常代碼結(jié)果
5! = 1 * 2 * 3 * 4 * 5 = 120
異常代碼結(jié)果
5! = 0 * 2 * 3 * 4 * 5 = 0
現(xiàn)在來調(diào)試代碼可能存在的問題,就要看 i 每一次的變量值,和 total 相應(yīng)的結(jié)果。
logging 日志記錄模塊
一、基本用法
#!python3
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('factorial函數(shù)開始運(yùn)行(%s)' % (n))
total = 1
for i in range(1, n + 1):
total *= i
logging.debug('i 為 ' + str(i) + ', total 為 ' + str(total))
logging.debug('factorai函數(shù)運(yùn)行結(jié)束(%s)' % (n))
return total
print('7! = ' + str(factorial(7)))
logging.debug('程序結(jié)束.')
運(yùn)行效果
2019-07-16 20:28:45,072 - [DEBUG] - 程序開始
2019-07-16 20:28:45,073 - [DEBUG] - factorial函數(shù)開始運(yùn)行(5)
2019-07-16 20:28:45,073 - [DEBUG] - i 為 0, total 為 0
2019-07-16 20:28:45,073 - [DEBUG] - i 為 1, total 為 0
2019-07-16 20:28:45,073 - [DEBUG] - i 為 2, total 為 0
2019-07-16 20:28:45,073 - [DEBUG] - i 為 3, total 為 0
2019-07-16 20:28:45,073 - [DEBUG] - i 為 4, total 為 0
2019-07-16 20:28:45,073 - [DEBUG] - i 為 5, total 為 0
2019-07-16 20:28:45,073 - [DEBUG] - factorai函數(shù)運(yùn)行結(jié)束(5)
5! = 0
2019-07-16 20:28:45,074 - [DEBUG] - 程序結(jié)束.
所以,我們可以看出,i 變量的數(shù)值從一開始就是 0 ,所以我們盡快定位問題所在。
并修改代碼為
for i in rang(1, n+1):
二、日志級(jí)別(由低到高)
| 級(jí)別 | 函數(shù)調(diào)用 | 描述 |
|---|---|---|
| DEBUG | logging.debug() | 最低級(jí)別。用于小細(xì)節(jié)。通常只有在診斷問題時(shí),你才會(huì)關(guān)心這些消息 |
| INFO | logging.info() | 用于記錄程序中一般事件的信息,或確認(rèn)一切工作正常 |
| WARNING | logging.warning() | 用于表示可能的問題,它不會(huì)阻止程序的工作,但將來可能會(huì) |
| ERROR | logging.error() | 用于記錄錯(cuò)誤,它導(dǎo)致程序做某事失敗 |
| CRITICAL | logging.critical() | 最高級(jí)別。用于表示致命的錯(cuò)誤,它導(dǎo)致或?qū)⒁獙?dǎo)致程序完全停止工作 |
三、將debug日志寫到文件中
logging.basicConfig(filename='D:\\py\\Auto\\debug\\myProgramLog.txt',
level=logging.DEBUG,
format="%(asctime)s - [%(levelname)s] - %(message)s")
將 filename 設(shè)置好后,所有 debug 消息就會(huì)寫入外部的文本文件,命令行就不會(huì)顯示了。
四、調(diào)試"開關(guān)"
這個(gè)功能,才是以后不用 print 來調(diào)試的正真的關(guān)鍵
logging.disable(logging.CRITICAL)
通常將它,放在 loggin.basicConfig() 下一行,并且先注釋掉。(可以看下實(shí)例代碼)
調(diào)試完成后,取消注釋,禁用所有調(diào)試信息輸出。
總結(jié)
- logging.disable(logging.CRITICAL),會(huì)禁止顯示,當(dāng)前級(jí)別,以及比當(dāng)前級(jí)別低的調(diào)試信息。
- format 可以自定義消息輸出的格式
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s - [%(levelname)s] - %(message)s"
)
format 設(shè)置好后字符串格式后,如下輸出
2019-07-16 20:28:45,073 - [DEBUG] - i 為 0, total 為 0
%(asctime)s --> 2019-07-16 20:28:45,073
\-
[%(levelname)s] --> [DEBUG]
\-
%(message)s --> logging.debug('i 為 ' + str(i) + ', total 為 ' + str(total))