抛出異常
當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