1. 程式人生 > >python 中 try...finally... 的優雅實現

python 中 try...finally... 的優雅實現

### 1. 關於 try.. finally.. 假如上帝用 python 為每一個來到世界的生物編寫程式,那麼除去中間過程的種種複雜實現,最不可避免的就是要保證每個例項最後都要掛掉。程式碼可簡寫如下: ```py try: born() # 出生 # 正常降臨世界 # do something.. except ValueError: # 安排錯誤 # do something... except AttributeError: # 特徵錯誤 # do something... except TypeError: # 種類錯誤 # do something... ... # 等等雜七雜八的錯誤 finally: go_die() # 掛掉 come_to_see_me() # 然後來見我 reincarnate() # 下一輪,安排! ``` 這就是 `finally` 的作用和例項。就算捕獲異常後再次出現異常,最終也能保證 `go_die` 方法會執行,但是,如果 `go_die` 方法出現錯誤,那麼就不能正常去見上帝了。為了保證每個生物(不管有沒有掛掉)都能見到上帝他老人家,並開始下一個輪迴(不管有沒有見到),需要做如下處理: ```py ... finally: try: go_die() finally: try: come_to_see_me() finally: reincarnate() ``` OK,功能雖然實現了,但按照 `The Zen of Python` 所說:`Flat is better than nested.`(扁平優於巢狀),那麼這段程式碼就略顯醜陋了。為了遵循 python 美學,我們可以對這段進行優化,使它看起來更為美觀。 ### 2. 錯誤的上下文:`__context__` 在此之前,需要引入一個新的概念: `__context__`,`__context__` 的字面意思就是上下文,它屬於錯誤的一個屬性。在錯誤捕獲中,它意味著當你處理一個錯誤時,另一個錯誤發生了。也就是說,你所捕獲的錯誤雖然被成功捕獲了,但當捕獲完成時,你的一些操作導致另一個錯誤發生,而這個錯誤並沒有被捕獲。通常情況下,如果處理的好,那麼**當前錯誤**的 `__context__` 的值為 `None`,如果處理不好那就是你所捕獲的錯誤。比如下面的程式碼: ```py def type_err(): raise TypeError('this is a type error.') def after_type_err(): raise ValueError('this is a value error.') try: type_err() except TypeError: after_type_err() ``` 執行結果為: ```python Traceback (most recent call last):