python中至少包括兩種錯誤:語法錯誤(syntax errors)和異常(exceptions)。 1.語法錯誤 語法錯誤,也被稱作解析錯誤 語法分析器指出錯誤行,並且在檢測到錯誤的位置前面顯示一個小“箭頭”。 錯誤是由箭頭前面的標記引起的(或者至少是這麼檢測的)。錯誤會輸出文件名和行號,所以如 ...
python中至少包括兩種錯誤:語法錯誤(syntax errors)和異常(exceptions)。
1.語法錯誤
語法錯誤,也被稱作解析錯誤
語法分析器指出錯誤行,並且在檢測到錯誤的位置前面顯示一個小“箭頭”。 錯誤是由箭頭前面的標記引起的(或者至少是這麼檢測的)。錯誤會輸出文件名和行號,所以如果是從腳本輸入的你就知道去哪裡檢查錯誤了。
2.異常
即使一條語句或表達式在語法上是正確的,當試圖執行它時也可能會引發錯誤。 運行期檢測到的錯誤稱為異常。此時會停止代碼的執行,而大多數異常是並沒有被處理的,所以會得到這樣的異常信息顯示:
列印錯誤信息時,異常的類型作為異常的內置名顯示。對於所有的內置異常都是如此,不過用戶自定義異常就不一定了(儘管這是一個很有用的約定)。標準異常名是內置的標識(沒有保留關鍵字)。
python的標準異常有以下這些:
異常名稱 | 描述 |
BaseException | 所有異常的基類 |
SystemExit | 解釋器請求退出 |
KeyboardInterrupt | 用戶中斷執行(通常是輸入ctrl+c) |
Exception | 常規錯誤的基類 |
StopIteration | 迭代器沒有更多的值 |
GeneratorExit | 生成器(generator)發生異常來通知退出 |
StandardError | 所有的內建標準異常的基類 |
ArithmeticError | 所有數值計算錯誤的基類 |
FloatingPointError | 浮點計算錯誤 |
OverflowError | 數值運算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (所有數據類型) |
AssertionError | 斷言語句失敗 |
AttributeError | 對象沒有這個屬性 |
EOFError | 沒有內建輸入,到達EOF 標記 |
EnvironmentError | 操作系統錯誤的基類 |
IOError | 輸入/輸出操作失敗 |
OSError | 操作系統錯誤 |
WindowsError | 系統調用失敗 |
ImportError | 導入模塊/對象失敗 |
LookupError | 無效數據查詢的基類 |
IndexError | 序列中沒有此索引(index) |
KeyError | 映射中沒有這個鍵 |
MemoryError | 記憶體溢出錯誤(對於Python 解釋器不是致命的) |
NameError | 未聲明/初始化對象 (沒有屬性) |
UnboundLocalError | 訪問未初始化的本地變數 |
ReferenceError | 弱引用(Weak reference)試圖訪問已經垃圾回收了的對象 |
RuntimeError | 一般的運行時錯誤 |
NotImplementedError | 尚未實現的方法 |
SyntaxError | Python 語法錯誤 |
IndentationError | 縮進錯誤 |
TabError | Tab 和空格混用 |
SystemError | 一般的解釋器系統錯誤 |
TypeError | 對類型無效的操作 |
ValueError | 傳入無效的參數 |
UnicodeError | Unicode 相關的錯誤 |
UnicodeDecodeError | Unicode 解碼時的錯誤 |
UnicodeEncodeError | Unicode 編碼時錯誤 |
UnicodeTranslateError | Unicode 轉換時錯誤 |
Warning | 警告的基類 |
DeprecationWarning | 關於被棄用的特征的警告 |
FutureWarning | 關於構造將來語義會有改變的警告 |
OverflowWarning | 舊的關於自動提升為長整型(long)的警告 |
PendingDeprecationWarning | 關於特性將會被廢棄的警告 |
RuntimeWarning | 可疑的運行時行為(runtime behavior)的警告 |
SyntaxWarning | 可疑的語法的警告 |
UserWarning | 用戶代碼生成的警告 |
當然,異常的觸發並不絕對導致程式的終止或崩潰,因為我們可以預見性地處理這些異常。
3.異常處理
我們可以使用 try/except 語句來捕捉並處理異常。
try/except語句用來檢測try語句塊中的錯誤,從而讓except語句捕獲異常信息並處理。
如果你不想在異常發生時結束你的程式,只需在try里捕獲它。
try 語句的執行順序:
1.首先,執行 try 子句 (在 try 和 except 關鍵字之間的部分)。
2.如果沒有異常發生, except 子句 在 try 語句執行完畢後就被忽略了。
3.如果在 try 子句執行過程中發生了異常,那麼該子句其餘的部分就會被忽略。如果異常匹配於 except 關鍵字後面指定的異常類型,就執行對應的 except 子句。然後繼續執行 try 語句之後的代碼。
4.如果發生了一個異常,在 except 子句中沒有與之匹配的分支,它就會傳遞到上一級 try 語句中。如果最終仍找不到對應的處理語句,它就成為一個未處理異常,終止程式運行,顯示提示信息。
while True: try: num = int(raw_input('請輸入一個數字:')) print num break except ValueError: print '非法字元' print '我在try之後'
示例中,當我輸入一個無法被轉換為數字的 @ 號時,本來應該觸發ValueError異常的。但是進行了異常處理了之後,當我輸入 @ 號時,異常被捕捉到了,同時執行了except中的語句,並執行了try之後的代碼。但因為是在永真的while迴圈中,所以又執行了一遍,這時我輸入了正確的數字,所以try中的語句能繼續執行下去,又遇到了break,迴圈退出。
一個 try 語句可能包含多個 except 子句(至少一個),分別指定處理不同的異常。至多只會有一個分支被執行。
try: '''嘗試各種操作'''
except IOError as e: '''捕捉到這種異常,就執行這裡的代碼'''
except ValueError: '''捕捉到這種異常,就執行這裡的代碼''' except: '''如果發生的異常不是上面的兩種,那麼剩下的異常都統一這樣處理'''
最後一個 except 子句可以省略異常名稱,以作為通配符使用。但是正以為它能捕捉任何的異常,所以一些在意料之外的異常也會被掩蓋掉。
我們也可以用一個except 子句捕捉多個異常,做統一的處理:
except (RuntimeError, TypeError, NameError): pass
這時又有同學好奇 except IOError as e: 是什麼意思,下麵看代碼演示:
while True: try: num = int(raw_input('請輸入一個數字:')) print num break except ValueError as msg: #等價於:except ValueError,msg: print msg
發現是報錯信息,和不做異常處理的下麵的一樣:
看看其類型是什麼:
print type(msg)
看看裡面有什麼方法:
print dir(msg)
非常多,一行顯示不完,不過多數是私有方法,我們重點關註後面的args,和message。
print msg.args print type(msg.args)
看來是將錯誤信息轉換成字元串後保存到元祖中。
print msg.message print type(msg.message)
看來就是把錯誤信息轉換成字元串。
try 除了可以配合 except使用之外,還能配合 else 和 finally 使用。
else子句只能出現在所有 except 子句之後。當 try 語句沒有拋出異常時,需要執行一些代碼,可以使用這個子句。
不管有沒有發生異常, finally子句在程式離開 try 後都一定會被執行。當 try 語句中發生了未被 except 捕獲的異常(或者它發生在 except 或 else 子句中),在 finally 子句執行完後它會被重新拋出。 try 語句經由 break ,continue 或 return 語句退出也一樣會執行 finally 子句。
while True: try: num = int(raw_input('請輸入一個數字:')) print num except ValueError, msg: print msg.message else: print '沒有異常的時候才會觸發' #當try中使用break ,continue 或 return 語句退出時,不執行 finally: print '無論如何我都會執行'
4.手動觸發異常:
raise 語句允許程式員強制拋出一個指定的異常。
要拋出的異常由 raise 的唯一參數標識。它必需是一個異常實例或異常類(繼承自 Exception 的類)。
如果你需要明確一個異常是否拋出,但不想處理它, raise 語句可以讓你很簡單的重新拋出該異常:
5.用戶自定義異常
在程式中可以通過創建新的異常類型來命名自己的異常(Python 類的內容請參見類)。異常類通常應該直接或間接的從 Exception 類派生,例如:
class MyError(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) try: raise MyError('錯誤信息') except MyError as msg: print msg.value print msg.args print '-----', msg.message
Exception 預設的 __init__() 被覆蓋。新的方式簡單的創建 value 屬性。這就替換了原來創建 args 屬性的方式。
6. assert 斷言
assert是用來檢查一個條件,如果它為真,就不做任何事。如果它為假,則會拋出AssertError並且包含錯誤信息。
格式: assert expression [, arguments] (expression:表達式,arguments:參數,多是字元串來說明錯誤)
a = 1 assert a < 5 assert a > 5, '根本沒有這會事'