標籤:等級 關於 return out inner int inter 簡單的 images
嵌套異常處理器
其實我們主要需要搞清楚的問題應該是這樣的,當異常發生的時候,無論是簡單的異常處理還是複雜的異常處理,我們都應該能夠清楚的瞭解到異常運行到哪裡,被誰捕獲了,現在控制權到了哪裡了,下面我們來分析嵌套異常處理的例子來說明上面說的這些問題。
以下是當異常發生的時候try/except和try/finally對於異常的處理:
下面我們將使用程式來看一下當異常發生的時候會出現什麼狀況:
使用嵌套的try/except的情況:
def action2(): print(1+[]) #TypeErrortry: try: action2() print(‘inner try‘) except TypeError: print(‘inner except‘) print(‘outer try‘)except TypeError: print(‘outter except‘)
運行結果如下
inner exceptouter try
我們主要的目的是要瞭解情況的控制權在什麼地方:當action2引發一個TypeError的時候,內部try/excpt的try模組後面資訊不會繼續執行,轉而執行except的資訊,當except將這個資訊捕獲的時候,執行except裡面的資訊,然後這個時候程式的控制權轉到了try/except外面,然後外面的try/except因為沒有發生異常,所以不會執行except裡面的代碼,程式繼續轉到try/except外面
try/finally是如何執行的
try: try: raise IndexError print(‘inner try‘) finally: print(‘inner finally‘) print(‘outer try‘)finally: print(‘outer finally‘)
執行後的結果如下:
inner finallyouter finallyTraceback (most recent call last): File "D:\application\eclipse\workspace\yichang\c4\t3.py", line 3, in <module> raise IndexErrorIndexError
說明當使用try/finally以後,當try當中出現錯誤的時候,執行完finally代碼塊以後,代碼就會繼續往上拋,不會進行錯誤的捕獲,最終拋到了頂層,由預設異常處理器進行處理
try/excpet/finally進行嵌套時候的代碼:
def raise1(): raise IndexErrordef raise2(): returndef raise3(): raise TypeErrorfor func in (raise1,raise2,raise3): try: print(‘inner try‘) try: func() except IndexError: print(‘inner except ‘) print(‘outer try‘) finally: print(‘outer finally‘) print(‘\n‘)
運行結果如下:
inner tryinner except outer tryouter finallyinner tryouter tryouter finallyinner tryouter finallyTraceback (most recent call last): File "D:\application\eclipse\workspace\yichang\c4\t4.py", line 9, in <module> func() File "D:\application\eclipse\workspace\yichang\c4\t4.py", line 3, in raise3 def raise3(): raise TypeErrorTypeError
異常的習慣用法
1:異常不總是錯誤
錯誤總是異常,異常不總是錯誤。其實在在程式啟動並執行過程當中,我們需要異常來配合我們的程式繼續運行。有些異常時一些訊號而已,比如EOFError還有SystemExit和KeyboardInterrupt異常等。
2:關閉檔案和伺服器串連
包括資料庫等串連等情況,其實都有一個關閉串連的過程,這個時候使用try/finally。現在,我們有有了新的選擇,那就是使用with/as來進行。
3:sys.exc_info
當使用空的except的時候,可以和sys.exc_info結合使用,來輸出一些有用的資訊,當有處理器處理的時候,sys_exc_info會存有(type,value,traceback)資訊,當沒有處理器處理錯誤的時候會返回(None,None,None)資訊。
與異常有關的技巧
1:應該封裝什麼異常
其實,主要是關於我們對於異常的態度,不要我們學了異常以後,我們啟動並執行任何代碼又要加上異常處理,這樣會讓我們顯得膽戰心驚。我們有時候其實並不需要進行異常捕獲,因為程式運行出現錯誤其實是我們需要的,我們可以修改這些錯誤。我們主要是在我們覺得經常會出現失敗的地方進行異常捕獲。try/finally則用在需要關閉的場所。在單個函數外面使用異常比在其內部使用多個異常好一些。
2:捕捉太多
當我們使用一個excpet的時候,我們可以捕獲所有的異常,這樣程式看上去異常的簡潔,你也可以放心的運行你的代碼,但是其實這個並不是很好的,我們應該能夠儘可能精確地捕獲我們需要的錯誤,否則,except會攔截我們程式不會出現的錯誤,分析下面的例子:
mydic = {1:‘a‘,2:‘b‘}try: x = mydic[3]except: x = Noneprint(x)
其實,我們的代碼的原意是這樣的,當我們出現KeyError的時候,我們的x的值為None。假如我們的字典名字出現了錯誤,我們想要引發異常或者做一點不一樣的事情,但是這個時候,我們的代碼還會讓x的值為None。
3:捕捉太少
捕捉太少出現的一個問題是,當我們修改程式的時候,我們需要在except裡面增加我們的異常,所以這個時候可以使用高一等級的異常,來應對這種變化的情況。
《python學習手冊》第35章 異常的設計