標籤:
try...except...finally
try 語句塊中異常發生點後的剩餘語句永遠不會到達(所以也永遠不會執行). 一旦一個異常被引發, 就必須決定控制流程下一步到達的位置. 剩餘代碼將被忽略, 解譯器將搜尋處理器, 一旦找到,就開始執行處理器中的代碼.
如果沒有找到合適的處理器, 那麼異常就向上移交給調用者去處理, 這意味著堆棧架構立即回到之前的那個. 如果在上層調用者也沒找到對應處理器, 該異常會繼續被向上移交, 直到找到合適處理器. 如果到達最頂層仍然沒有找到對應處理器, 那麼就認為這個異常是未處理的, Python 解譯器會顯示出跟蹤返回訊息, 然後退出.
ps:避免把大片的代碼裝入 try-except 中然後使用 pass 忽略掉錯誤. 你可以捕獲特定的異常並忽略它們, 或是捕獲所有異常並採取特定的動作. 不要捕獲所有異常,然後忽略掉它們.
try: print ‘try...‘ r = 10 / 0 print ‘result:‘, rexcept ZeroDivisionError, e: print ‘except:‘, efinally: print ‘finally...‘print ‘END‘
異常參數 e 是一個包含來自導致異常的代碼的診斷資訊的類執行個體。 print except:‘, e 其實是調用了e的__str__方法。
如果只是想返回這個資訊,可使用str()。
def safe_float(object): try: retval = float(object) except (ValueError, TypeError), diag: retval = str(diag) return retval
with及上下文管理
參考連結:淺談 Python 的 with 語句
with 語句作為 try/finally 編碼範式的一種替代,用於對資源訪問進行控制的場合。
with語句適用於對資源進行訪問的場合,確保不管使用過程中是否發生異常都會執行必要的“清理”操作,釋放資源,比如檔案使用後自動關閉、線程中鎖的自動擷取和釋放等。
with語句的用法
with context_expression [as target(s)]: with-body
自訂上下文管理器
ontext_manager.__enter__() :進入上下文管理器的運行時上下文,在語句體執行前調用。如果指定了 as 子句,with 語句將該方法的傳回值賦值給 as 子句中的 target。
context_manager.__exit__(exc_type, exc_value, exc_traceback) :退出與上下文管理器相關的運行時上下文,該方法返回一個布爾值表示是否對發生的異常進行處理。exc_type, exc_value, exc_traceback參數表示引起退出操作的異常,如果退出時沒有發生異常,則3個參數都為None。發生異常時,如果不想處理異常,則將函數傳回值設定為True;如果想處理異常,只需要將傳回值設定為 False 就可以了(不要顯示重新拋出異常,即不要重新拋出通過參數傳遞進來的異常)。之後,上下文管理代碼會檢測是否 __exit__() 失敗來處理異常,並在退出該方法後重新拋出異常以由 with 語句之外的代碼邏輯進行處理。(ps:如果該方法內部產生異常,則會取代由 statement-body 中語句產生的異常。)
class DummyResource: def __init__(self, tag): self.tag = tag print ‘Resource [%s]‘ % tag def __enter__(self): print ‘[Enter %s]: Allocate resource.‘ % self.tag return self # 可以返回不同的對象 def __exit__(self, exc_type, exc_value, exc_tb): print ‘[Exit %s]: Free resource.‘ % self.tag if exc_tb is None: print ‘[Exit %s]: Exited without exception.‘ % self.tag else: print ‘[Exit %s]: Exited with exception raised.‘ % self.tag return False # 可以省略,預設的None也是被看做是False</span>with DummyResource(‘Normal‘): print ‘[with-body] Run without exceptions.‘----------------------------------------------------Resource [Normal] [Enter Normal]: Allocate resource. [with-body] Run without exceptions. [Exit Normal]: Free resource. [Exit Normal]: Exited without exception.with DummyResource(‘With-Exception‘): print ‘[with-body] Run with exception.‘ raise Exception print ‘[with-body] Run with exception. Failed to finish statement-body!‘--------------------------Resource [With-Exception] [Enter With-Exception]: Allocate resource. [with-body] Run with exception. [Exit With-Exception]: Free resource. [Exit With-Exception]: Exited with exception raised. Traceback (most recent call last): File "G:/demo", line 20, in <module> raise Exception Exception
可以看到,正常執行時會先執行完語句體 with-body,然後執行 __exit__() 方法釋放資源。with-body 中發生異常時with-body 並沒有執行完,但資源會保證被釋放掉,同時產生的異常由 with 語句之外的代碼邏輯來捕獲處理。
raise拋出錯誤
只有在必要的時候才定義我們自己的錯誤類型。如果可以選擇Python已有的內建的錯誤類型(比如ValueError,TypeError),盡量使用Python內建的錯誤類型。
class FooError(StandardError): passdef foo(s): n = int(s) if n==0: raise FooError(‘invalid value: %s‘ % s) return 10 / n
assert
def foo(s): n = int(s) assert n != 0, ‘n is zero!‘ #assert的意思是,運算式n != 0應該是True,否則,後面的代碼就會出錯。 return 10 / ndef main(): foo(‘0‘)
常見的錯誤類型和繼承關係
BaseException +-- SystemExit +-- KeyboardInterrupt +-- GeneratorExit +-- Exception +-- StopIteration +-- StandardError | +-- BufferError | +-- ArithmeticError | | +-- FloatingPointError | | +-- OverflowError | | +-- ZeroDivisionError | +-- AssertionError | +-- AttributeError | +-- EnvironmentError | | +-- IOError | | +-- OSError | | +-- WindowsError (Windows) | | +-- VMSError (VMS) | +-- EOFError | +-- ImportError | +-- LookupError | | +-- IndexError | | +-- KeyError | +-- MemoryError | +-- NameError | | +-- UnboundLocalError | +-- ReferenceError | +-- RuntimeError | | +-- NotImplementedError | +-- SyntaxError | | +-- IndentationError | | +-- TabError | +-- SystemError | +-- TypeError | +-- ValueError | +-- UnicodeError | +-- UnicodeDecodeError | +-- UnicodeEncodeError | +-- UnicodeTranslateError +-- Warning +-- DeprecationWarning +-- PendingDeprecationWarning +-- RuntimeWarning +-- SyntaxWarning +-- UserWarning +-- FutureWarning +-- ImportWarning +-- UnicodeWarning +-- BytesWarning
2015-05-27
python之錯誤和異常