一宣吱、簡介
Python最強大的結(jié)構(gòu)之一就是它的異常處理能力窃这,所有的標準異常都使用類來實現(xiàn),都是基類Exception的成員征候,都從基類Exception繼承杭攻,而且都在exceptions模塊中定義。Python自動將所有異常名稱放在內(nèi)建命名空間中疤坝,所以程序不必導入exceptions模塊即可使用異常兆解。一旦引發(fā)而且沒有捕捉SystemExit異常,程序執(zhí)行就會終止跑揉。異常的處理過程锅睛、如何引發(fā)或拋出異常及如何構(gòu)建自己的異常類都是需要深入理解的。
二历谍、詳解
1现拒、什么是異常
(1)錯誤
從軟件方面來說英遭,錯誤是語法或邏輯上的双肤。語法錯誤指示軟件的結(jié)構(gòu)上有錯誤飘言,導致不能被解釋器解釋或編譯器無法編譯钧嘶。這些錯誤必須在程序執(zhí)行前糾正。邏輯錯誤可能是由于不完整或是不合法的輸入所致露乏,在其他情況下傀蓉,還可能是邏輯無法生成撩幽、計算或是輸出結(jié)果需要的過程無法執(zhí)行捐韩,這些錯誤通常分別被稱為域錯誤和范圍錯誤退唠。
當Python檢測到一個錯誤時,解釋器就會指出當前流已經(jīng)無法繼續(xù)執(zhí)行下去荤胁。這時候就出現(xiàn)了異常瞧预。
(2)異常
對異常的最好描述是:它是因為程序出現(xiàn)了錯誤而在正常控制流以外采取的行為仅政。這個行為又分為兩個階段:首先是引起異常發(fā)生的錯誤垢油,然后是檢測和采取可能的措施階段。
第一個階段是在發(fā)生了一個異常條件(有時候也叫做例外的條件)后發(fā)生的已旧。只要檢測到錯誤并且意識到異常條件秸苗,解釋器會引發(fā)一個異常召娜。引發(fā)也可以叫做觸發(fā)运褪、引發(fā)或者生成。 解釋器通過它通知當前控制流有錯誤發(fā)生,Python也允許程序員自己引發(fā)異常秸讹。第二階段是:無論是 Python 解釋器還是程序員引發(fā)的檀咙,異常就是錯誤發(fā)生的信號, 當前流將被打斷璃诀,用來處理這個錯誤并采取相應的操作弧可。對異常的處理發(fā)生在第二階段, 異常引發(fā)后劣欢,可以調(diào)用很多不同的操作棕诵。可以是忽略錯誤(記錄錯誤但不采取任何措施凿将,采取補救措施后終止程序)校套,或是減輕問題的影響后設(shè)法繼續(xù)執(zhí)行程序。所有的這些操作都代表一種繼續(xù)牧抵,或是控制的分支笛匙。關(guān)鍵是程序員在錯誤發(fā)生時可以指示程序如何執(zhí)行。
Python采用了"try/嘗試"塊和"catching/捕獲"塊的概念犀变,而且它在異常處理方面更有"紀律性"妹孙。可以為不同的異常創(chuàng)建不同的處理器获枝, 而不是盲目地創(chuàng)建一個"catch-all/捕獲所有"的代碼蠢正。
2、Python中的異常
不管是通過Python解釋器執(zhí)行還是標準的腳本執(zhí)行映琳,所有的錯誤都符合相似的格式机隙, 這提供了一個一致的錯誤接口。所有錯誤萨西,無論是語意上的還是邏輯上的有鹿,都是由于和Python解釋器不相容導致的,其后果就是引發(fā)異常谎脯。
NameError:嘗試訪問一個未申明的變量葱跋, 任何可訪問的變量必須在名稱空間里列出, 訪問變量需要由解釋器進行搜索源梭,如果請求的名字沒有在任何名稱空間里找到娱俺,那么將會生成一個NameError異常。
ZeroDivisionError:除數(shù)為零废麻;SyntaxError:Python 解釋器語法錯誤荠卷;IndexError:請求的索引超出序列范圍;KeyError:請求一個不存在的字典關(guān)鍵字烛愧;IOError:輸入/輸出錯誤油宜;AttributeError:嘗試訪問未知的對象屬性掂碱。
3、檢測和處理異常
異成髟可以通過 try 語句來檢測疼燥,任何在try語句塊里的代碼都會被監(jiān)測, 檢查有無異常發(fā)生蚁堤。try 語句有兩種主要形式: try-except和try-finally 醉者。這兩個語句是互斥的, 即只能使用其中的一種披诗。一個try語句可以對應一個或多個except子句撬即,但只能對應一個finally子句,或是一個try-except-finally復合語句呈队「爿海可以使用try-except語句檢測和處理異常,也可以添加一個可選的else子句處理沒有探測到異常的時執(zhí)行的代碼掂咒,而try-finally只允許檢測異常并做一些必要的清除工作(無論發(fā)生錯誤與否)才沧。
(1)try-except語句
try-except 語句(以及其更復雜的形式)定義了進行異常監(jiān)控的一段代碼,并且提供了處理異常的機制绍刮。
try-except 語句語法:
try:
try_suite # watch for exceptions here監(jiān)控這里的異常
except Exception[, reason]: # exception-handling code異常處理代碼
except_suite
在程序運行時温圆,解釋器嘗試執(zhí)行try塊里的所有代碼,如果代碼塊完成后沒有異常發(fā)生孩革,執(zhí)行流就會忽略except語句繼續(xù)執(zhí)行岁歉。而當except語句所指定的異常發(fā)生后,會保存了錯誤的原因膝蜈,控制流立即跳轉(zhuǎn)到對應的處理器(try子句的剩余語句將被忽略)锅移。
(2)封裝內(nèi)建函數(shù)
交互操作:把一個用字符串表示的數(shù)值轉(zhuǎn)換為正確的數(shù)值表示形式,其中float()增加了把字符串表示的數(shù)值轉(zhuǎn)換為浮點數(shù)的功能饱搏,替換以前的string.atof()非剃。 float()對參數(shù)要求嚴格,例如如果參數(shù)的類型正確(字符串)推沸,其值不可轉(zhuǎn)換為浮點數(shù)备绽,那么將引發(fā) ValueError異常;若參數(shù)是列表鬓催,因為類型不正確肺素,所以引發(fā)一個TypeError異常。
def safe_float(obj):
try:
retval = float(obj)
except ValueError:
retval = 'could not convert non-number to float'
return retval
(3)帶有多個except 的try語句
把多個except語句連接在一起宇驾, 處理一個try塊中可能發(fā)生的多種異常倍靡。
except Exception1[, reason1]:
suite_for_exception_Exception1
except Exception2[, reason2]:
suite_for_exception_Exception2
程序首先嘗試執(zhí)行try子句,如果沒有錯誤课舍,忽略所有的except從句繼續(xù)執(zhí)行塌西。如果發(fā)生異常蜗顽,解釋器將在這一串處理器(except 子句)中查找匹配的異常, 如果找到對應的處理器雨让,執(zhí)行流將跳轉(zhuǎn)到這里。
Python支持把except語句串連使用忿等,分別為每個異常類型分別創(chuàng)建對應的錯誤信息栖忠,這樣用戶可以得到更詳細的關(guān)于錯誤的信息。
def safe_float(obj):
try:
retval = float(obj)
except ValueError:
retval = 'could not convert non-number to float'
except TypeError:
retval = 'object type cannot be converted to float'
return retval
(4)處理多個異常的except語句
except 語句可以處理任意多個異常贸街,但要求異常被放在一個元組里庵寞。
except (Exc1[, Exc2[, ... ExcN]])[, reason]:
suite_for_exceptions_Exc1_to_ExcN
如:
def safe_float(obj):
try:
retval = float(obj)
except (ValueError, TypeError):
retval = 'argument must be a number or numeric string'
return retval
(5)捕獲所有異常
捕獲所有的異常的代碼:
try:
pass
except Exception, e:
# error occurred, log 'e', etc.
或不太推薦的方法是使用裸except子句(無任何錯誤信息,以后可能會不再支持):
try:
pass
except:
# error occurred, etc.
異常部分內(nèi)容在Python 2.5有了一些變化薛匪,異常被遷移到了new-style class上捐川,啟用了一個新的"所有異常的母親",這個類叫做 BaseException逸尖。異常的繼承結(jié)構(gòu)有了少許調(diào)整古沥,KeyboardInterrupt和SystemExit被從Exception里移出,和Exception平級娇跟。
- BaseException
|- KeyboardInterrupt
|- SystemExit
|- Exception
|- (all other current built-in exceptions) 所有當前內(nèi)建異常
若需要捕獲所有異常岩齿,那么就可以使用新的BaseException:
try:
pass
except BaseException, e:
# handle all errors
注意:避免把大片的代碼裝入try-except中然后使用pass忽略掉錯誤,可以捕獲特定的異常并忽略它們苞俘,或是捕獲所有異常并采取特定的動作.盹沈,不要捕獲所有異常,然后忽略掉它們吃谣。
(6)異常參數(shù)
異常也可以有參數(shù)乞封,異常引發(fā)后它會被傳遞給異常處理器。當異常被引發(fā)后參數(shù)是作為附加幫助信息傳遞給異常處理器的岗憋。雖然異常原因是可選的肃晚,但標準內(nèi)建異常提供至少一個參數(shù),指示異常原因的一個字符串仔戈。異常的參數(shù)可以在處理器里忽略陷揪, 但 Python提供了保存這個值的語法。要想訪問提供的異常原因杂穷,必須保留一個變量來保存這個參數(shù)悍缠,把這個參數(shù)放在except語句后,接在要處理的異常后面耐量。except 語句的這個語法可以被擴展為:
# single exception
except Exception[, reason]:
suite_for_Exception_with_Argument
# multiple exceptions
except (Exception1, Exception2, ..., ExceptionN)[, reason]:
suite_for_Exception1_to_ExceptionN_with_Argument
其中reason將會是一個包含來自導致異常的代碼的診斷信息的類實例飞蚓。異常參數(shù)自身會組成一個元組,并存儲為類實例(異常類的實例)的屬性廊蜒,reason將會是一個Exception類的實例趴拧。
無論reason只包含一個字符串或是由錯誤編號和字符串組成的元組溅漾,調(diào)用 str(reason) 總會返回一個良好可讀的錯誤原因,因為 reason是一個類實例著榴,這樣其實是調(diào)用類的特殊方法str() 添履。
唯一的問題就是某些第三方或是其他外部庫并不遵循標準協(xié)議, 推薦在引發(fā)自己的異常時遵循異常參數(shù)規(guī)范脑又,用和已有Python代碼一致錯誤信息作為傳給異常的參數(shù)元組的一部分暮胧。如:若引發(fā)一個ValueError,那么最好提供和解釋器引發(fā)ValueError時一致的參數(shù)信息问麸。
(7)在應用使用我們封裝的函數(shù)
處理一個文件往衷,將其作為字符串讀入,并用一個日志文件跟蹤處理進程严卖。
#!/usr/bin/env python
def safe_float(object):
'safe version of float()'
try:
retval = float(object)
except (TypeError, ValueError), diag:
retval = str(diag)
return retval
def main():
'handles all the data processing'
log = open('cardlog.txt', 'w')
try:
ccfile = open('carddata.txt', 'r')
except IOError, e:
log.write('no txns this month\n')
log.close()
return
txns = ccfile.readlines()
ccfile.close()
total = 0.00
log.write('account log:\n')
for eachTxn in txns:
result = safe_float(eachTxn)
if isinstance(result, float):
total += result
log.write('data... processed\n')
else:
log.write('ignored: %s' % result)
print '$%.2f (new balance)' % (total)
log.close()
if __name__ == '__main__':
main()
其中從文件中提取數(shù)據(jù)席舍,這里的文件打開被置于try-except語句段中。內(nèi)建的isinstance()函數(shù)檢查結(jié)果類型哮笆,檢查safe_float是返回字符串還是浮點數(shù)来颤,任何字符串都意味著錯誤,表明該行不能轉(zhuǎn)換為數(shù)字稠肘,同時所有的其他數(shù)字可以作為浮點數(shù)累加入total脚曾,在 main()函數(shù)的尾行會顯示最終生成的余額。
(8)else子句
在try范圍中沒有異常被檢測到時即結(jié)束前沒有引發(fā)異常启具,然后執(zhí)行else子句本讥。如:
try:
function()
except:
pass
else:
pass
(9)finally子句
finally子句是無論異常是否發(fā)生、是否捕捉都會執(zhí)行的一段代碼鲁冯】椒校可以將finally僅僅配合try一起使用,也可以和 try-except(else也是可選的)一起使用薯演。
try-except-else-finally 語法的示例:
try:
A
except MyException:
B
else:
C
finally:
D
(10)try-finally語句
另一種使用finally的方式是finally單獨和try連用撞芍。這個try-finally語句和try-except區(qū)別在于它不是用來捕捉異常的。作為替代跨扮,它常常用來維持一致的行為序无,無論 try中是否有異常觸發(fā),finally 代碼段都會被執(zhí)行衡创。
try:
try_suite
finally: #無論如何都執(zhí)行
finally_suite
當在try范圍中產(chǎn)生一個異常時帝嗡,會立即跳轉(zhuǎn)到finally語句段。當finally中的所有代碼都執(zhí)行完畢后璃氢,會繼續(xù)向上一層引發(fā)異常哟玷。
讀取數(shù)據(jù)的代碼:
try:
ccfile = open('carddata.txt', 'r')
txns = ccfile.readlines()
ccfile.close()
except IOError:
log.write('no txns this month\n')
其中的缺陷:若按照這樣的順序發(fā)生錯誤,打開成功但出于一些原因readlines()調(diào)用失敗一也,異常處理會去繼續(xù)執(zhí)行except中的子句巢寡,而不去嘗試關(guān)閉文件喉脖。通過try-finally來優(yōu)化:
ccfile = None
try:
try:
ccfile = open('carddata.txt', 'r')
txns = ccfile.readlines()
except IOError:
log.write('no txns this month\n')
finally:
if ccfile:
ccfile.close()
另一種可選的實現(xiàn)切換了try-except和try-finally包含的方式:
ccfile = None
try:
try:
ccfile = open('carddata.txt', 'r')
txns = ccfile.readlines()
finally:
if ccfile:
ccfile.close()
except IOError:
log.write('no txns this month\n')
上述方法唯一的問題是:當finally中的代碼引發(fā)了另一個異常或由于return抑月、break树叽、continue語法而終止,會丟失原來異常的上下文信息導致原來的異常無法重新引發(fā)谦絮,除非也事先保存题诵。
(11)try-except-else-finally:廚房一鍋端
語法樣式:
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
其中else和finally都是可選的,而必須至少要有一個except子句挨稿。
4、上下文管理
(1)with 語句
另一個隱藏低層次的抽象的例子是with語句京痢,它在Python 2.6中正式啟用(以前必必須用from future import with_statement來導入它)奶甘。
with 語句的目的在于從流程圖中把try、except和finally關(guān)鍵字和資源分配釋放相關(guān)代碼統(tǒng)統(tǒng)去掉祭椰,而不是像try-except-finally那樣僅僅簡化代碼使之易用臭家。 with 語法的基本用法:
with context_expr [as var]:
with_suite
file和with一起使用的代碼片段:
with open('/etc/passwd', 'r') as f:
for eachLine in f:
# ...do stuff with eachLine or f...
這段代碼試圖打開一個文件,如果一切正常方淤,把文件對象賦值給f钉赁;然后用迭代器遍歷文件中的每一行,當完成時關(guān)閉文件携茂。無論在這一段代碼的開始你踩、中間還是結(jié)束時發(fā)生異常,都會執(zhí)行清理的代碼讳苦,此外文件仍會被自動的關(guān)閉带膜。可以看出Python已經(jīng)拿走了一堆細節(jié)鸳谜,實際上只是進行了兩層處理:第一膝藕,用戶層 ,和in類似所需要關(guān)心的只是被使用的對象咐扭;第二芭挽,對象層,既然這個對象支持上下文管理協(xié)議蝗肪,它干的也就是"上下文管理"袜爪。
5、字符串作為異常
早在Python 1.5前薛闪,標準的異常是基于字符串實現(xiàn)的饿敲。然而,這樣就限制了異常之間不能有相互的關(guān)系逛绵,這種情況隨著異常類的來臨而不復存在怀各。到1.5后倔韭,所有的標準異常都是類了,但程序員還是可以用字符串作為自己的異常的(建議使用異常類)瓢对。在2.5中寿酌,觸發(fā)字符串異常會導致一個警告,2.6中捕獲字符串異常會導致一個警告硕蛹。
6醇疼、觸發(fā)異常
有些異常由程序執(zhí)行期間的錯誤而引發(fā),程序員在編寫API時希望遇到錯誤的輸入時觸發(fā)異常法焰,為此Python提供了一種機制讓程序員明確的觸發(fā)異常秧荆,即raise語句。
(1)raise語法
raise 語句支持的參數(shù)十分靈活埃仪,語法上支持許多不同的格式乙濒。rasie一般的用法:raise [SomeException [, args [, traceback]]]。
第一個參數(shù)卵蛉,SomeExcpetion是觸發(fā)異常的名字颁股。如果有,它必須是一個字符串傻丝、類或?qū)嵗视小H绻衅渌麉?shù)(arg或traceback),就必須提供SomeExcpetion.Python的標準異常葡缰。
第二個符號為可選的args(比如參數(shù),值)來傳給異常亏掀,這可以是一個單獨的對象也可以是一個對象的元組。當異常發(fā)生時泛释,異常的參數(shù)總是作為一個元組傳入幌氮。如果args原本就是元組,那么就將其傳給異常去處理胁澳;如果args是一個單獨的對象该互,就生成只有一個元素的元組(就是單元素元組)。大多數(shù)情況下韭畸,單一的字符串用來指示錯誤的原因宇智。如果傳的是元組,通常的組成是一個錯誤字符串胰丁,一個錯誤編號随橘,可能還有一個錯誤的地址比如文件等等。
最后一項參數(shù)traceback锦庸,同樣是可選的(實際上很少用它)机蔗。如果有的話,則是當異常觸發(fā)時新生成的一個用于異常-正常化(exception-normally)的追蹤(traceback)對象萝嘁。當你想重新引發(fā)異常時梆掸,第三個參數(shù)很有用(可以用來區(qū)分先前和當前的位置)。如果沒有這個參數(shù)牙言,就填寫None酸钦。
(2) raise慣用法
最常見的用法為SomeException是一個類,不需要其他的參數(shù)咱枉,但如果有的話卑硫,可以是一個單一對象參數(shù)、一個參數(shù)的元組或一個異常類的實例蚕断。如果參數(shù)是一個實例欢伏,可以由給出的類及其派生類實例化(已存在異常類的子集)。若參數(shù)為實例亿乳,則不能有更多的其他參數(shù)硝拧。
(3)raise少見的慣用法
當參數(shù)是一個實例 , 該實例若是給定異常類的實例當然不會有問題风皿,然而如果該實例并非這個異常類或其子類的實例時河爹,那么解釋器將使用該實例的異常參數(shù)創(chuàng)建一個給定異常類的新實例匠璧。 如果該實例是給定異常類子類的實例桐款, 那么新實例將作為異常類的子類出現(xiàn), 而不是原來的給定異常類夷恍。
如果raise語句的額外參數(shù)不是一個實例——作為替代魔眨,是一個單件(singleton)或元組,那么將用這些作為此異常類的初始化的參數(shù)列表酿雪。如果不存在第二個參數(shù)或是None遏暴,則參數(shù)列表為空。
如果SomeException是一個實例指黎,就無需對什么進行實例化了朋凉。這種情況下,不能有額外的參數(shù)或只能是None醋安。異常的類型就是實例的類杂彭;也就是說,等價于觸發(fā)此類異常吓揪,并用該實例為參數(shù)比如:raiseinstance.class,instance亲怠。
還有一個可選的參量(args)作參數(shù).
最后,這種不含任何參數(shù)的raise語句結(jié)構(gòu)是在Python1.5中新引進的柠辞,會引發(fā)當前代碼塊(code block)最近觸發(fā)的一個異常团秽。如果之前沒有異常觸發(fā),會因為沒有可觸發(fā)的異常而生成一TypeError異常。
(4)raise的不同用法
由于raise有許多不同格式有效語法(比如:SomeException 可以是類习勤、實例或一個字符串)踪栋,以下總結(jié)下rasie 的不同用法:
7、斷言
斷言是一句必須等價于布爾真的判定姻报;此外己英,發(fā)生異常也意味著表達式為假(類似C中預處理器的assert宏),但在Python中它們在運行時構(gòu)建(與之相對的是編譯期判別)吴旋。 斷言通過 assert 語句實現(xiàn)损肛。可以簡簡單單的想象為raise-if語句(更準確的說是raise-if-not 語句)荣瑟。測試一個表達式治拿,若返回值是假,觸發(fā)異常笆焰。
斷言語句劫谅,如果斷言成功不采取任何措施(類似語句),否則觸發(fā)AssertionError(斷言錯誤)的異常嚷掠。assert 的語法如下:assert expression[, arguments]捏检。AssertionError異常和其他的異常一樣可以用try-except語句塊捕捉,但是如果沒有捕捉不皆,它將終止程序運行而且提供一個traceback贯城。
如同raise 語句一樣,也可以提供一個異常參數(shù)給assert 命令:
>>> try:
... assert 1 == 0, 'One does not equal zero silly!'
... except AssertionError, args:
... print '%s: %s' % (args.__class__.__name__, args)
...
AssertionError: One does not equal zero silly!
assert 如何運作霹娄,可以通過函數(shù)類似實現(xiàn)(內(nèi)建的變量debug在通常情況下為True):
def assert(expr, args=None):
if __debug__ and not expr:
raise AssertionError, args
8能犯、標準異常
所有的異常都是內(nèi)建的, 所以它們在腳本啟動前或在互交命令行提示符出現(xiàn)時已經(jīng)是可用的了犬耻。
Python內(nèi)建異常:
所有的標準/內(nèi)建異常都是從根異常派生的踩晶。目前有3個直接從BaseException派生的異常子類:SystemExit、KeyboardInterrupt和Exception枕磁,其他的所有的內(nèi)建異常都是Exception的子類渡蜻。
到了Python2.5,所有的異常的都是新風格(new-style)的類计济,并且最終都是BaseException的子類茸苇。從Python1.5到Python2.4.x,異常是標準的類峭咒,它們是字符串税弃。從Python2.5開始,不再支持構(gòu)建基于字符串的異常并且被正式的棄用凑队,即不能再觸發(fā)一個字符串異常了则果,將不能捕獲它們幔翰。還有一個就是所有新的異常最終都是BaseException的子類,以便于它們有一個統(tǒng)一的接口西壮。
9遗增、sys和相關(guān)模塊
(1)sys模塊
另一種獲取異常信息的途徑是通過sys模塊中exc_info()函數(shù),此功能提供了一個3元組(3-tuple)的信息款青。
>>> try:
... float('abc123')
... except:
... import sys
... exc_tuple = sys.exc_info()
...
>>> print exc_tuple
(<type 'exceptions.ValueError'>, ValueError('invalid literal for float(): abc123',), <traceback object at 0x7ff79c87dc20>)
>>> for eachItem in exc_tuple:
... print eachItem
...
<type 'exceptions.ValueError'>
invalid literal for float(): abc123
<traceback object at 0x7ff79c87dc20>
sys.exc_info()得到的元組中是:exc_type異常類做修;exc_value異常類的實例;exc_traceback追蹤(traceback)對象抡草。第三項,饰及,是一個新增的追蹤(traceback)對象,這一對象提供了的發(fā)生異常的上下文康震,它包含諸如代碼的執(zhí)行幀燎含,異常發(fā)生時的行號等信息。在舊版本中的Python中腿短,這三個值分別存在于sys模塊屏箍,為sys.exc_type、sys.exc_value和sys.exc_traceback 橘忱,但這三者是全局變量而不是線程安全的赴魁, 建議用sys.exc_info()來代替。
(2)相關(guān)模塊
模塊 描述
exceptions 內(nèi)建異常(永遠不用導入這個模塊)
contextlib 為使用 with 語句的上下文對象工具
sys 包含各種異常相關(guān)的對象和函數(shù)(見sys.ex)
三钝诚、總結(jié)
(1)Python異常不僅簡化代碼颖御,而且簡化整個錯誤管理體系,異常處理促使成熟和正確的編程敲长。
(2)可以通過創(chuàng)建一個從內(nèi)置的Exception類繼承的類定義自己的異常郎嫁,然后使用raise命令引發(fā)異潮蹋或傳遞異常祈噪。