python: 錯誤和異常

一宣吱、簡介

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ā)異潮蹋或傳遞異常祈噪。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市尚辑,隨后出現(xiàn)的幾起案子辑鲤,更是在濱河造成了極大的恐慌,老刑警劉巖杠茬,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件月褥,死亡現(xiàn)場離奇詭異,居然都是意外死亡瓢喉,警方通過查閱死者的電腦和手機宁赤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來栓票,“玉大人决左,你說我怎么就攤上這事。” “怎么了佛猛?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵惑芭,是天一觀的道長。 經(jīng)常有香客問我继找,道長遂跟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任婴渡,我火速辦了婚禮幻锁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己鬼譬,他們只是感情好馋评,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著究飞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪堂鲤。 梳的紋絲不亂的頭發(fā)上亿傅,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音瘟栖,去河邊找鬼葵擎。 笑死,一個胖子當著我的面吹牛半哟,可吹牛的內(nèi)容都是我干的酬滤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼寓涨,長吁一口氣:“原來是場噩夢啊……” “哼盯串!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起戒良,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤体捏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后糯崎,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體几缭,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年沃呢,在試婚紗的時候發(fā)現(xiàn)自己被綠了年栓。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡薄霜,死狀恐怖某抓,靈堂內(nèi)的尸體忽然破棺而出竿刁,到底是詐尸還是另有隱情,我是刑警寧澤搪缨,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布食拜,位于F島的核電站,受9級特大地震影響副编,放射性物質(zhì)發(fā)生泄漏负甸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一痹届、第九天 我趴在偏房一處隱蔽的房頂上張望呻待。 院中可真熱鬧,春花似錦队腐、人聲如沸蚕捉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迫淹。三九已至,卻和暖如春为严,著一層夾襖步出監(jiān)牢的瞬間敛熬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工第股, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留应民,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓夕吻,卻偏偏與公主長得像诲锹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子涉馅,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 希望大家喜歡归园,點贊哦 Python錯誤和異常處理概略 一、錯誤和異常的概念 1.1 錯誤:代碼運行前的語法或者邏輯...
    Gaolex閱讀 2,088評論 0 4
  • 定義類并創(chuàng)建實例 在Python中控漠,類通過 class 關(guān)鍵字定義蔓倍。以 Person 為例悬钳,定義一個Person類...
    績重KF閱讀 3,948評論 0 13
  • Python異常處理 異常概念: 異常:就是不正常的情況盐捷,程序開發(fā)過程中錯誤和BUG都是補充正常的情況 異常發(fā)生的...
    youngkun閱讀 924評論 0 4
  • http://python.jobbole.com/85231/ 關(guān)于專業(yè)技能寫完項目接著寫寫一名3年工作經(jīng)驗的J...
    燕京博士閱讀 7,571評論 1 118
  • 第十一章 使用加載項自定義ArcGIS界面 ||| 附錄A 自動執(zhí)行Python腳本 我們將在本章介紹以下案例: ...
    muyan閱讀 8,975評論 0 2