Python 異常處理以及with 語句的使用
try …except…else 語句
是處理異常公式, try 是有可能拋異常的程式碼塊, except 抓取異常的型別, else 是指當沒有抓到拋錯,就執行這塊程式碼。請看下下邊的例子:
try: print("抓取的有可能的程式碼塊") raise IOError except IOError as e: print("except IOError") except OSError as e: print("except OSError") else: print("other erro") finally: print("i am finally") #列印結果: 抓取的有可能的程式碼塊 except IOError i am finally
從結果來看 走的路線是: try(按照raise 的error 找except)>找到except並執行except程式碼塊>執行finally語句塊 如果沒有拋錯走的路線是: try 沒有error>走else 語句>finally 看來不管有沒有錯誤, finally 語句一定會執行到。 在用到finally 要注意他會覆蓋 except or else 的返回值。
def try_list(): try: print("抓取的有可能的程式碼塊") raise OSError return 1 except IOError as e: print("except IOError") return 2 except OSError as e: print("except OSError") return 3 else: print("other erro") return 4 finally: print("i am finally") return 5 print(try_list()) #列印結果 抓取的有可能的程式碼塊 except IOError i am finally 5
從列印的結果 ,他覆蓋了 return 3。 如果走else路線同樣return 的4 也會被覆蓋, 自己試試下。 那小夥伴有疑問 什麼情況下使用 finally 呢 答案: 是在釋放資源的時候, 看下邊的例子。
def try_list(): try: fp=open("Test。txt") raise OSError fp.close() except IOError as e: fp.close() except OSError as e: fp.close() print("except OSError") else: print("other erro") fp.close()
大家看了 嗎, 只要有流程的分支的地方一定要加上這個 fp.close(), 如果再加分支,還需要再加這個close 函式。 有沒有更好的解決方法嗎? 答案就是 用finally。請看下邊的程式碼:
def try_list():
try:
fp=open("Test。txt")
raise OSError
except IOError as e:
except OSError as e:
print("except OSError")
else:
print("other erro")
finally:
fp.close()
大家看看是不是很神奇, 資源的釋放不光是檔案的關閉,還有socket 連線,資料庫的連線。
上邊的內容只是複習下異常處理的內容, 下邊才是重頭戲 with上下文管理器 。
with上下文管理器
with上下文管理器協議包括兩個魔法函式 1.__enter__2.exit 用例項來解釋下這兩個魔法函式
class Person:
def __enter__(self): #獲取資源
print("enter")
def __exit__(self, exc_type, exc_val, exc_tb): #釋放資源
print("exit")
def said(self):
print("said")
with Person() as P:
P.said()
列印結果是: enter Traceback (most recent call last): exit File “C:/Users/tengfei/PycharmProjects/test1/alert.py”, line 12, in P.said() AttributeError: ‘NoneType’ object has no attribute ‘said’
根據提示我們就知道了, 我們例項化是“NoneType” 型別,意思就是空的物件。
原因是 因為我們在獲取資源(enter)沒有返回值,所以預設返回的是空。 我們加上 返回值 就可以執行成功瞭如下:
class Person:
def __enter__(self): #並沒有呼叫,也會執行這個函式
print("enter")
# return self
def __exit__(self, exc_type, exc_val, exc_tb): #並沒有呼叫,也會執行這個函式
print("exit")
def said(self):
print("said")
with Person() as P:
P.said()
列印結果: enter #並沒有呼叫,也會執行這個函式 said exit #並沒有呼叫,也會執行這個函式
總結: 上下文管理器協議 是用with 進行呼叫,預設呼叫了 enter 和 exit 兩個魔法函式。 with是對try…expect…finally語法的一種簡化,並且提供了對於異常非常好的處理方式。 根據實際需要應用在不同的場景。