課時33:異常處理:你不可能總是對的2

那是個好男孩發表於2018-08-21

目錄:

  一、try-except語句

  二、try-finally語句

  三、raise語句

  四、課時33課後習題及答案

 

**********************

一、try-except語句

**********************

try-except語句格式如下:

try:
    檢測範圍
except Exception[as reason]:
    出現異常(Exception)後的處理程式碼

 try-except語句用於檢測和處理異常,舉個例子來說明這一切是如何操作的:

f = open("我為什麼是一個文件.txt")
print(f.read())
f.close()

以上程式碼在“我為什麼是一個文件.txt”這個文件不存在的時候,Python就會報錯說檔案不存在:

Traceback (most recent call last):
  File "C:Users14158Desktoplalallalalal.py", line 1, in <module>
    f = open("我為什麼是一個文件.txt")
FileNotFoundError: [Errno 2] No such file or directory: `我為什麼是一個文件.txt`

顯然這樣的使用者體驗很糟糕,因此可以這樣修改:

try:
      f = open("我為什麼是一個文件.txt")
      print(f.read())
      f.close()
except OSError:
      print("檔案開啟的過程出錯啦")
      

上面的例子由於使用了大家習慣的語言來表達錯誤的資訊,使用者體驗當然會好很多:

檔案開啟的過程出錯啦

但是從程式設計師的角度來看,導致OSError異常的原因有很多(例如FileExistsError、FileNotFoundError等等),所以可能會更在意錯誤的具體內容,這裡可以使用as把具體的錯誤資訊給列印出來:

try:
      f = open("我為什麼是一個文件.txt")
      print(f.read())
      f.close()
except OSError as reason:
      print("檔案開啟的過程出錯啦,錯誤的原因是:" + str(reason))
      
      
檔案開啟的過程出錯啦,錯誤的原因是:[Errno 2] No such file or directory: `我為什麼是一個文件.txt`

 

1、針對不同異常設定多個except

一個try語句還可以和多個except語句搭配,分別對感興趣的異常進行檢測處理:

try:
      sum = 1 + `1`
      f = open("我是一個不存在的文件.txt")
      print(f.read())
      f.close()
except OSError as reason:
      print("檔案開啟的過程出錯啦,錯誤的原因是:" + str(reason))
except TypeError as reason:
      print("檔案開啟的過程出錯啦,錯誤的原因是:" + str(reason))
      
      
檔案開啟的過程出錯啦,錯誤的原因是:unsupported operand type(s) for +: `int` and `str`

 

2、對多個異常統一處理

except後邊還可以跟多個異常,然後對這些異常進行統一的處理:

try:
      int("abc")
      sum = 1 + "1"
      f = open("我是一個不存在的文件.txt")
      print(f.read())
      f.close()
except (OSError,TypeError):
      print("檔案開啟的過程出錯啦,錯誤的原因是:" + str(reason))
      
      
Traceback (most recent call last):
  File "C:Users14158Desktoplalallalalal.py", line 2, in <module>
    int("abc")
ValueError: invalid literal for int() with base 10: `abc`

 

3、捕獲所有的異常

如果你無法確定要對哪一類異常進行處理,只是希望在try語句塊裡一旦出現異常,可以給使用者一個“看得懂”的提醒,那麼可以這麼做。

…………

except:

  print(“出錯了~”)

…………

不過通常不建議這麼做,因為它會隱藏所有程式設計師未想到並且未做好處理準備的錯誤,例如當使用者輸入ctrl+C試圖終止程式,卻被解釋為KeyboardInterrupt異常。另外要注意的是,try語句檢測範圍內一旦出現異常,剩下的語句將不會執行。

 

*********************

二、try-finally語句

*********************

 如果“我是一個不存在的文件”確實存在,open()函式正常返回檔案物件,但異常卻發生在成功開啟檔案後的sum = 1 + “1”語句上。此時python將直接跳轉到except語句,也就是說,檔案被開啟了,但並沒有執行關閉的命令:

try:
      f = open("我是一個不存在的文件.txt")
      print(f.read())
      sum = 1 + "1"
      f.close()
except:
      print("出錯啦")       

為了實現像這種“就算出現異常,但不得不執行的收尾工作(比如在程式崩潰前儲存使用者文件)”,引入了finally來擴充套件try:

try:
      f = open("我是一個不存在的文件.txt")
      print(f.read())
      sum = 1 + "1"
except:
      print("出錯啦")
finally:
      f.close()

如果try語句塊中沒有出現任何執行時出現的錯誤,會跳過except語句執行finally語句塊的內容。如果出現異常,則會先執行except語句塊的內容再執行finally語句塊的內容。總之,finally語句塊中的內容就是確保無論如何都將被執行的內容。

 

****************

三、raise語句

****************

 也許會問,我的程式碼能不能自己丟擲一個異常呢?答案是可以的,可以使用raise語句丟擲一個異常:

>>> raise ZeroDivisionError
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    raise ZeroDivisionError
ZeroDivisionError

丟擲的異常還可以帶引數,表示異常的解釋:

>>> raise ZeroDivisionError("除數不能為零!")
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    raise ZeroDivisionError("除數不能為零!")
ZeroDivisionError: 除數不能為零!

 

*******************************

四、課時33課後習題及答案

*******************************

相關文章