?? 8.html
字號:
<HTML><!-- Mirrored from www.math.pku.edu.cn/teachers/lidf/docs/Python/8.html by HTTrack Website Copier/3.x [XR&CO'2005], Fri, 08 Jul 2005 11:49:14 GMT --><HEAD><TITLE>第八章 錯誤與例外</TITLE></HEAD><BODY><H1>第八章 錯誤與例外</H1><P>到現(xiàn)在為止我們只是提到了錯誤信息而沒有詳細(xì)討論,如果你運(yùn)行了前面的例子可能已經(jīng)看到了一些錯誤信息。至少有兩種不同錯誤:句法錯和例外錯(exceptions)。</P><H2>8.1 句法錯</H2><P> 句法錯也稱為語法分析錯,是你在學(xué)習(xí)Python的時候最可能犯的錯誤。<PRE>>>> while 1 print 'Hello world' File "<stdin>", line 1 while 1 print 'Hello world' ^SyntaxError: invalid syntax</PRE><P>語法分析器重復(fù)出錯行,并用一個小‘箭頭’指向行內(nèi)最早發(fā)現(xiàn)錯誤的位置。錯誤是由箭頭前面的記號引起的(至少是在這里檢測到的)。在本例中,錯誤在關(guān)鍵字print處檢測到,因?yàn)樗懊鎽?yīng)該有一個冒號(“:”)。錯誤信息中顯示了文件名和行號這樣如果錯誤發(fā)生在一個腳本文件中你就知道到哪里去找。</P><H2>8.2 例外</H2><P>即使語句或表達(dá)式句法沒有問題,在試圖運(yùn)行的時候也可能發(fā)生錯誤。運(yùn)行時檢測到的錯誤叫做例外,這種錯誤不一定必然是致命的:你很快就會學(xué)到如何在Python程序中處理例外。然而,多數(shù)例外不能被程序處理,這是會產(chǎn)生錯誤信息,如:</P><PRE>>>> 10 * (1/0)Traceback (innermost last): File "<stdin>", line 1ZeroDivisionError: integer division or modulo>>> 4 + spam*3Traceback (innermost last): File "<stdin>", line 1NameError: spam>>> '2' + 2Traceback (innermost last): File "<stdin>", line 1TypeError: illegal argument type for built-in operation</PRE><P>錯誤信息的最后一行顯示發(fā)生的情況。例外有不同的類型,類型作為錯誤信息的一部分顯示:上例中錯誤的類型有ZeroDivisionError、NameError和TypeError。作為例外類型顯示的字符串是發(fā)生的例外的內(nèi)置名。這對于所有內(nèi)置例外成立,但對用戶自定義例外不一定成立(用戶最好能遵守這樣的約定)。標(biāo)準(zhǔn)例外名是內(nèi)置的標(biāo)識符(不是保留關(guān)鍵字)。</P><P>此行的其余部分是錯誤的細(xì)節(jié),其解釋依賴于例外類型。錯誤信息前面的部分以堆棧反跟蹤的形式顯示了發(fā)生錯誤的上下文環(huán)境。一般這包含了列出源代碼行的一個列出源程序行的堆棧反跟蹤;然而,它不會顯示從標(biāo)準(zhǔn)輸入讀進(jìn)的行。</P><P> 庫參考手冊列出了內(nèi)置例外和其含義。 <H2>8.3 例外處理</H2><P> 可以編程序來處理選定的例外。請看下面的例子,顯示一些浮點(diǎn)數(shù)的倒數(shù):<PRE>>>> numbers = [0.3333, 2.5, 0, 10]>>> for x in numbers:... print x,... try:... print 1.0 / x... except ZeroDivisionError:... print '*** has no inverse ***'... 0.3333 3.000300032.5 0.40 *** has no inverse ***10 0.1</PRE><P>try語句是這樣工作的:</P><UL><LI>首先,運(yùn)行try子句(在try和except之間的語句)。</LI><LI>如果沒有發(fā)生例外,跳過except子句,try語句運(yùn)行完畢。</LI><LI>如果在try子句中發(fā)生了例外錯誤而且例外錯誤匹配except后指定的例外名,則跳過try子句剩下的部分,執(zhí)行except子句,然后繼續(xù)執(zhí)行try語句后面的程序。</LI><LI>如果在try子句中發(fā)生了例外錯誤但是例外錯誤不匹配except后指定的例外名,則此例外被傳給外層的try語句。如果沒有找到匹配的處理程序則此例外稱作是未處理例外,程序停止運(yùn)行,顯示錯誤信息。</LI></UL><P>try語句可以有多個except子句,為不同的例外指定不同處理。至多只執(zhí)行一個錯誤處理程序。錯誤處理程序只處理相應(yīng)的try子句中發(fā)生的例外,如果同try語句中其它的錯誤處理程序中發(fā)生例外錯誤處理程序不會反應(yīng)。一個except子句可以列出多個例外,寫在括號里用逗號分開,例如:</P><PRE>... except (RuntimeError, TypeError, NameError):... pass</PRE><P>最后一個except子句可以省略例外名,作為一個通配項(xiàng)。這種方法要謹(jǐn)慎使用,因?yàn)檫@可能會導(dǎo)致程序?qū)嶋H已出錯卻發(fā)現(xiàn)不了。</P><P>try ... except語句有一個可選的else子句,如有的話要放在所有except子句之后。else的意思是沒有發(fā)生例外,我們可以把try子句中沒有發(fā)生例外時要做的事情放在這個子句里。例如:</P><PRE>for arg in sys.argv[1:]: try: f = open(arg, 'r') except IOError: print '不能打開', arg else: print arg, '有', len(f.readlines()), '行' f.close()</PRE><P>例外發(fā)生時可能伴有一個值,叫做例外的參數(shù)。參數(shù)是否存在及其類型依賴于例外的類型。對于有參數(shù)的例外,except在自居可以在例外名(或表)后指定一個變量用來接受例外的參數(shù)值,如:</P><PRE>>>> try:... spam()... except NameError, x:... print 'name', x, 'undefined'... name spam undefined</PRE><P>有參數(shù)的例外未處理時會在錯誤信息的最后細(xì)節(jié)部分列出其參數(shù)值。 <P>例外處理程序不僅處理直接產(chǎn)生于try子句中的例外,也可以處理try子句中調(diào)用的函數(shù)(甚至是間接調(diào)用的函數(shù))中的例外。如:</P><PRE>>>> def this_fails():... x = 1/0... >>> try:... this_fails()... except ZeroDivisionError, detail:... print 'Handling run-time error:', detail... Handling run-time error: integer division or modulo</PRE><H2>8.4 產(chǎn)生例外</H2><P>raise語句允許程序員強(qiáng)行產(chǎn)生指定的例外。例如:<PRE>>>> raise NameError, 'HiThere'Traceback (innermost last): File "<stdin>", line 1NameError: HiThere</PRE><P>raise語句的第一個參數(shù)指定要產(chǎn)生的例外的名字。可選的第二參數(shù)指定例外的參數(shù)。 <H2>8.5 用戶自定義例外</H2><P>程序中可以定義自己的例外,只要把一個字符串賦給一個變量即可。例如:<PRE>>>> my_exc = 'my_exc'>>> try:... raise my_exc, 2*2... except my_exc, val:... print 'My exception occurred, value:', val... My exception occurred, value: 4>>> raise my_exc, 1Traceback (innermost last): File "<stdin>", line 1my_exc: 1</PRE><P>許多標(biāo)準(zhǔn)模塊用這種方法報告自己定義的函數(shù)中發(fā)生的錯誤。 <H2>8.6 定義清理動作</H2><P> try語句還有另一個finally可選子句,可以用來規(guī)定不論出錯與否都要執(zhí)行的動作。例如:</P><PRE>>>> try:... raise KeyboardInterrupt... finally:... print 'Goodbye, world!'... Goodbye, world!Traceback (innermost last): File "<stdin>", line 2KeyboardInterrupt</PRE><P>finally子句不論try子句中是否發(fā)生例外都會執(zhí)行。例外發(fā)生時,先執(zhí)行finally子句然后重新提出該例外。當(dāng)try語句用break或return語句退出時也將執(zhí)行finally子句。</P><P>要注意的是,try語句有了except子句就不能有finally子句,有了finally子句就不能有except子句,不能同時使用except子句和finally子句。需要的話可以嵌套。</P></BODY><!-- Mirrored from www.math.pku.edu.cn/teachers/lidf/docs/Python/8.html by HTTrack Website Copier/3.x [XR&CO'2005], Fri, 08 Jul 2005 11:49:14 GMT --></HTML>
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -