錯(cuò)誤和異常
錯(cuò)誤和異常在程序設(shè)計(jì)中是兩個(gè)不同的概念。這兩個(gè)概念又有著密切聯(lián)系。
錯(cuò)誤是客觀存在的一個(gè)現(xiàn)象。錯(cuò)誤就在那里,不聲不響。
錯(cuò)誤分為語法錯(cuò)誤和邏輯錯(cuò)誤。
語法錯(cuò)誤是靜態(tài)的,編譯/解釋程序會(huì)發(fā)現(xiàn)這些語法錯(cuò)誤,并輔助我們糾正這些語法錯(cuò)誤。
邏輯錯(cuò)誤動(dòng)態(tài)的,是運(yùn)算邏輯不完整不正確,會(huì)導(dǎo)致程序運(yùn)行失敗。
異常是一種手段措施,是系統(tǒng)發(fā)現(xiàn)程序運(yùn)行出錯(cuò)后,為避免程序失敗,中斷正常控制流程并采取的措施。這個(gè)措施分為兩個(gè)階段:首先發(fā)布錯(cuò)誤信息(拋出異常),其次處理這個(gè)錯(cuò)誤并采取相應(yīng)的操作。
在Python語言中所說異常還表示異常對(duì)象,就是將錯(cuò)誤發(fā)生時(shí)的狀態(tài)信息封裝為一個(gè)對(duì)象。我們所謂拋出異常就是生成這個(gè)異常對(duì)象并讓這個(gè)對(duì)象能被訪問。異常對(duì)象一般是由系統(tǒng)拋出,但也可以由程序主動(dòng)拋出。
try- except 語句:
try:
normal code piece # 系統(tǒng)會(huì)監(jiān)控這段代碼是否有錯(cuò)誤發(fā)生,如果有會(huì)拋出相應(yīng)的異常對(duì)象。
exceptException[, reason]: #程序可以捕獲指定異常對(duì)象并做進(jìn)一步的處理。
except code piece # 捕獲異常后的處理代碼。
說明:
reason將會(huì)是一個(gè)包含來自導(dǎo)致異常的代碼的診斷信息的類實(shí)例. 異常參數(shù)自身會(huì)組成一個(gè)元組,并存儲(chǔ)為類實(shí)例(異常類的實(shí)例)的屬性. 上邊的第一種用法中, reason 將會(huì)是一個(gè)Exception 類的實(shí)例. 對(duì)于大多內(nèi)建異常, 也就是從 StandardError 派生的異常, 這個(gè)元組只包含一個(gè)指示錯(cuò)誤原因的字符串. 一般說來, 異常的名字已經(jīng)是一個(gè)滿意的線索了, 但這個(gè)錯(cuò)誤字符串會(huì)提供更多的信息. 操作系統(tǒng)或其他環(huán)境類型的錯(cuò)誤, 例如 IOError , 元組中會(huì)把操作系統(tǒng)的錯(cuò)誤編號(hào)放在錯(cuò)誤字符串前. 無論 reason 只包含一個(gè)字符串或是由錯(cuò)誤編號(hào)和字符串組成的元組, 調(diào)用 str(reason) 總會(huì)返回一個(gè)良好可讀的錯(cuò)誤原因. 不要忘記 reason 是一個(gè)類實(shí)例 - 這樣做你其實(shí)是調(diào)用類的特殊方法 __str__() . 我們將在第 13 章探索面向?qū)ο缶幊讨械倪@些特殊方法. 唯一的問題就是某些第三方或是其他外部庫并不遵循這個(gè)標(biāo)準(zhǔn)協(xié)議. 我們推薦你在引發(fā)你自己的異常時(shí)遵循這個(gè)標(biāo)準(zhǔn)(參見核心風(fēng)格筆記).
擴(kuò)展支持:
1. 多個(gè)excption子句依次捕獲不同的異常。
except ValueError:
retval = 'could not convert non-number tofloat'
except TypeError:
retval = 'object type cannot be convertedto float'
2. 一個(gè)exception子句中捕獲多個(gè)不同的異常。要求異常被放在一個(gè)元組里:
except (Exception1, Exception2)[, reason]:
3. 捕獲所有異常:
except Exception, e: 或者 except: (裸except子句)
4. else子句當(dāng)沒有異常發(fā)生時(shí)運(yùn)行。
5. finally子句無論如何都會(huì)被運(yùn)行。
完整的異常處理的語法模板:
try:
try_suite
except Exception1:
suite_for_Exception1
except (Exception2,Exception3, Exception4):
suite_for_Exceptions_2_3_and_4
except Exception5,Argument5:
suite_for_Exception5_plus_argument
except (Exception6,Exception7), Argument67:
suite_for_Exceptions6_and_7_plus_argument
except:
suite_for_all_other_exceptions
else:
no_exceptions_detected_suite
finally:
always_execute_suite
主動(dòng)拋出異常:
raise[SomeException [, args [, traceback]]], 參數(shù)說明如下:
第一個(gè)參數(shù),SomeExcpetion,是觸發(fā)異常的名字.如果有,它必須是一個(gè)字符串,類或?qū)嵗?
第二個(gè)符號(hào)為可選的 args(比如參數(shù),值),來傳給異常.這可以是一個(gè)單獨(dú)的對(duì)象也可以是一個(gè)對(duì)象的元組.當(dāng)異常發(fā)生時(shí),異常的參數(shù)總是作為一個(gè)元組傳入.如果 args 原本就是元組,那么就將其傳給異常去處理;如果 args 是一個(gè)單獨(dú)的對(duì)象,就生成只有一個(gè)元素的元組(就是單元素元組).
最后一項(xiàng)參數(shù),traceback,同樣是可選的(實(shí)際上很少用它),如果有的話,則是當(dāng)異常觸發(fā)時(shí)新生成的一個(gè)用于異常-正常化(exception—normally)的追蹤(traceback)對(duì)象.
斷言拋出異常:
斷言對(duì)一個(gè)條件表達(dá)式進(jìn)行判斷。正常應(yīng)返回真,如果運(yùn)行時(shí)該條件表達(dá)式為假則拋出斷言異常AssertionError. 語法如下:
assert exPRession[,arguments]
AssertionError 異常和其他的異常一樣可以用 try-except語句塊捕捉,但是如果沒有捕捉,它將終止程序運(yùn)行而且提供一個(gè)traceback:
Traceback(innermost last): File "<stdin>", line 1, in ?
AssertionError
對(duì)于斷言觸發(fā)的異常AssertError,可以提供一個(gè)參數(shù),捕獲這個(gè)斷言異常的exception子句中的args可以獲取這個(gè)參數(shù)。
try:
assert 1 == 0, 'One does not equal zerosilly!'
except AssertionError,args:
print '%s: %s' % (args.__class__.__name__,args)
從命令行執(zhí)行上面的代碼會(huì)導(dǎo)致如下的輸出:
AssertionError: Onedoes not equal zero silly!
常見內(nèi)建異常:
異常名稱 描述
BaseException 所有異常的基類
SystemExit python 解釋器請(qǐng)求退出
KeyboardInterrupt 用戶中斷執(zhí)行(通常是輸入^C)
Exception 常規(guī)錯(cuò)誤的基類
StopIteration 迭代器沒有更多的值
GeneratorExit 生成器(generator)發(fā)生異常來通知退出
SystemExit Python 解釋器請(qǐng)求退出
StandardError 所有的內(nèi)建標(biāo)準(zhǔn)異常的基類
ArithmeticError 所有數(shù)值計(jì)算錯(cuò)誤的基類
FloatingPointError 浮點(diǎn)計(jì)算錯(cuò)誤
OverflowError 數(shù)值運(yùn)算超出最大限制
ZeroDivisionError 除(或取模)零 (所有數(shù)據(jù)類型)
AssertionError 斷言語句失敗
AttributeError 對(duì)象沒有這個(gè)屬性
EOFError 沒有內(nèi)建輸入,到達(dá) EOF 標(biāo)記
EnvironmentError 操作系統(tǒng)錯(cuò)誤的基類
IOError 輸入/輸出操作失敗
OSError 操作系統(tǒng)錯(cuò)誤
WindowsError Windows 系統(tǒng)調(diào)用失敗
ImportError 導(dǎo)入模塊/對(duì)象失敗
KeyboardInterrupt 用戶中斷執(zhí)行(通常是輸入^C)
LookupError 無效數(shù)據(jù)查詢的基類
IndexError 序列中沒有沒有此索引(index)
KeyError 映射中沒有這個(gè)鍵
MemoryError 內(nèi)存溢出錯(cuò)誤(對(duì)于 Python 解釋器不是致命的)
NameError 未聲明/初始化對(duì)象 (沒有屬性)
UnboundLocalErrorh 訪問未初始化的本地變量
ReferenceErrore 弱引用(Weak reference)試圖訪問已經(jīng)垃圾回收了的對(duì)象
RuntimeError 一般的運(yùn)行時(shí)錯(cuò)誤
NotImplementedError 尚未實(shí)現(xiàn)的方法
SyntaxError Python 語法錯(cuò)誤
IndentationError 縮進(jìn)錯(cuò)誤
TabError Tab 和空格混用
SystemError 一般的解釋器系統(tǒng)錯(cuò)誤
TypeError 對(duì)類型無效的操作
ValueError 傳入無效的參數(shù)
UnicodeError Unicode 相關(guān)的錯(cuò)誤
UnicodeDecodeError Unicode 解碼時(shí)的錯(cuò)誤
UnicodeEncodeError Unicode 編碼時(shí)錯(cuò)誤
UnicodeTranslateError Unicode 轉(zhuǎn)換時(shí)錯(cuò)誤
Warning j 警告的基類
DeprecationWarning 關(guān)于被棄用的特征的警告
FutureWarning 關(guān)于構(gòu)造將來語義會(huì)有改變的警告
OverflowWarning 舊的關(guān)于自動(dòng)提升為長整型(long)的警告
PendingDeprecationWarning 關(guān)于特性將會(huì)被廢棄的警告
RuntimeWarning 可疑的運(yùn)行時(shí)行為(runtimebehavior)的警告
SyntaxWarning 可疑的語法的警告
UserWarning 用戶代碼生成的警告
自定義異常:
def class <SelfExceptionName>(<BaseExceptionName>):
pass
自定義一個(gè)繼承了BaseExcetpton的異常類,什么也不做。對(duì)與自定義異常,只能通過raise語句拋出。
異常發(fā)生時(shí),sys.exc_info() 函數(shù)可以獲取當(dāng)前的異常信息。返回一個(gè)三元組(exc_type,exc_value,exc_traceback)
新聞熱點(diǎn)
疑難解答
網(wǎng)友關(guān)注