天天看點

調試

抛出異常

當python試圖執行無效代碼時,就會抛出異常。

可以使用try和except語句來處理python的異常,讓程式從預期的異常中恢複。

可以在代碼中抛出異常,“停止運作這個函數中的代碼,将程式執行轉到except語句"。

抛出異常使用raise語句。如果沒有try和except語句覆寫抛出異常的raise語句,該程式就會崩潰,并顯示異常的出錯資訊。

使用try和except語句,可以更優雅的處理錯誤,而不是讓整個程式崩潰。

通常是調用該函數的代碼知道如何處理異常,而不是該函數本身。

>>> raise Exception('This is a exception message.')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception: This is a exception message.      
>>> try:
...     guessOne(99)
... except Exception as err:
...     print('Exception message: '+str(err))
...
Exception message: name 'guessOne' is not defined      

反向跟蹤

如果python遇到錯誤,它會生成一些錯誤資訊,稱為”反向跟蹤“。反向跟蹤包含了出錯消息、導緻該錯誤的代碼行号,以及導緻該錯誤的函數調用的序列。這個序列稱為”調用棧“。

隻要抛出的異常沒有被處理,python就會顯示反向追蹤。可以調用traceback.format_exc(),得到它的字元串形式。在調用該函數之前,需要導入traceback子產品。

[root@juispan tmp]# cat 1.py
def a():
        b()
def b():
        raise Exception('ERROR!!!')
a()
[root@juispan tmp]# python3 1.py
Traceback (most recent call last):
  File "1.py", line 5, in <module>
    a()
  File "1.py", line 2, in a
    b()
  File "1.py", line 4, in b
    raise Exception('ERROR!!!')
Exception: ERROR!!!      

斷言

斷言的檢查,確定代碼沒有做出什麼明顯錯誤的事情。

斷言會抓住錯誤,清楚的告訴我們出了什麼錯。

assert語句是說:”我斷言這個條件為真,如果不為真,程式中什麼地方就有一個缺陷。“

不像異常,代碼不應該用try和except處理assert語句。

斷言針對的是程式員的錯誤,而不是使用者的錯誤。對于那些可以恢複的錯誤,請抛出異常,而不是用assert語句檢測它。

在運作python時傳入-O選項,可以禁用斷言,進而稍稍提高性能。如python -O test.py

>>> door='open'
>>> assert door == 'open','abnormal.'
>>> door='shut'
>>> assert door == 'open','abnormal.'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: abnormal.      

日志

使用python的logging子產品很容易建立自定義的消息記錄。

這些日志消息将描述程式執行何時到達日志函數調用,并列出指定的任何變量當時的值。另一方面,缺失日志資訊表明有一部分代碼被跳過,從未執行。

當python記錄一個事件的日志時,它會建立一個LogRecord對象,儲存關于該事件的資訊。logging子產品的函數指定想要看到的這個LogRecord對象的細節,以及希望的細節展示方式。

不要用print()調試,删除時容易誤操作。

加入一條logging.disable(l)調用,就可以禁止日志。它将禁用它之後的所有消息。可以加在import logging之後,通過注釋和取消注釋,啟用或禁用它。

要啟用logging子產品,可以執行以下代碼:

import logging
logging.basicConfig(filename='mylog.txt',level=logging.DEBUG,format=' %(asctime)s - %(levelname)s - %(message)s')        ##如果不需要存入檔案,可取消傳遞filename參數      

當我們向列印日志資訊時,使用logging.debug()函數。這個debug()函數将調用basicConfig(),列印一行資訊。資訊的格式在basicConfig()函數中指定,包括傳遞給debug()的消息。

級  别 子產品函數 作  用
DEBUG  logging.debug()  最低級别。用于小細節。通常用于診斷問題。
INFO  logging.info() 用于記錄程式中的一般事件的資訊,或确認一切工作正常。
WARNING logging.warning() 用于表示可能的問題,它不會阻止程式的工作,但将來可能會。
ERROR  logging.error()  用于記錄錯誤,它導緻程式做某事失敗。
CRITICAL  logging.critical() 最進階别。用于表示緻命的錯誤,它導緻或将要導緻程式完全停止工作。
[root@juispan tmp]# cat 1.py
import logging
logging.basicConfig(level=logging.DEBUG,format=' %(asctime)s - %(levelname)s - %(message)s')
#logging.disable(logging.DEBUG)
logging.debug('start')
def sum(a,b):
        count=0
        for num in range(a,b+1):
                count+=num
                logging.debug('Now sum is: '+str(count))
sum(5,10)
logging.debug('end')
[root@juispan tmp]# python3 1.py
 2017-07-21 01:58:44,200 - DEBUG - start
 2017-07-21 01:58:44,200 - DEBUG - Now sum is: 5
 2017-07-21 01:58:44,200 - DEBUG - Now sum is: 11
 2017-07-21 01:58:44,200 - DEBUG - Now sum is: 18
 2017-07-21 01:58:44,200 - DEBUG - Now sum is: 26
 2017-07-21 01:58:44,200 - DEBUG - Now sum is: 35
 2017-07-21 01:58:44,200 - DEBUG - Now sum is: 45
 2017-07-21 01:58:44,200 - DEBUG - end
[root@juispan tmp]# cat 1.py
import logging
logging.basicConfig(level=logging.DEBUG,format=' %(asctime)s - %(levelname)s - %(message)s')
logging.disable(logging.DEBUG)           ##關閉debug日志
logging.debug('start')
def sum(a,b):
        count=0
        for num in range(a,b+1):
                count+=num
                logging.debug('Now sum is: '+str(count))
sum(5,10)
logging.debug('end')
[root@juispan tmp]# python3 1.py      
上一篇: 調試
下一篇: 調試

繼續閱讀