1. 程式人生 > 其它 >大爽Python入門教程 7-5 異常處理 try ... except Exception

大爽Python入門教程 7-5 異常處理 try ... except Exception

大爽Python入門公開課教案 點選檢視教程總目錄

1 什麼是異常Exception

簡單來講,錯誤Error就是異常Exception

具體的,我們先來看幾個錯誤。

>>> 2:3
SyntaxError: illegal target for annotation
>>> 2 + ""
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    2 + ""
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> int("")
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    int("")
ValueError: invalid literal for int() with base 10: ''

這裡面的SyntaxErrorTypeErrorValueError是報錯。
指出了錯誤的具體型別(大概情況)

所有這些Error類,其根本類(始祖)是Exception
Exception是其父類或者其父類的父類,或者其父類的父類的父類...)

Error類的具體繼承關係,可以看官方文件:
exception-hierarchy

當然,很多時候並不需要分這麼清楚。
平時描述,基本報錯和異常是一個意思。

2 處理異常

介紹

一般來講,有錯誤,就會導致程式直接終止。

但有時候,我們希望報錯不會影響程式執行。
或者需要判斷錯誤是否執行。
那麼就需要使用try...except語法來處理錯誤。

舉個例子,我們之前接受使用者輸入時,會用isdigit來判斷輸入是否能轉換成數字。

現在我們有了新方法,如下

try:
    i = input()
    i = int(i)
    print(i)
except Exception as e:
    print(e)

執行時
如果輸入為數字,比如12, 則輸出對應數字12

如果輸入不是數字,比如dsafd
則輸出invalid literal for int() with base 10: 'dsafd'
注意:這個時候程式不是報錯終止,而是把錯誤列印了出來。

也就是使用者輸入數字的時候,
try管轄的程式碼的會正常執行,except

管轄的不會執行。

輸入不是數字導致程式無法執行的時候(int(i)報錯的時候)
try管轄的程式碼的會停止執行,
except管轄的程式碼會執行。

語法

try...except...的基本格式為

try:
    # statement1
except:
    # statement2

該語法效果為,
先嚐試執行try管轄的statement1程式碼,如果遇到異常,則停止。
去執行except管轄的statement2程式碼。

從中文上講,except可以理解為捕獲(異常)的意思。

有時候我們需要知道具體發生了什麼異常,將異常輸出或者做其他使用的時候,
則會使用except Exception as e,如下

try:
    # statement1
except Exception as e:
    # statement2

此時except Exception as e這一句中的as e
會把捕獲到的異常賦值給e,然後可以在statement2中使用。
(此時e是區域性變數,只能在except管轄的statement2中使用)

as e中的e只是一個變數名,並不是固定語法,可以起自己需要的名字。

示例分析

我們知道,數字和字串無法直接加減。會報錯
比如這個程式碼

x = "12" + 12

直接執行會報錯如下

Traceback (most recent call last):
  File "H:\github projects\big-shuang-python-introductory-course\codes\course7\demo502.py", line 1, in <module>
    x = "12" + 12
TypeError: can only concatenate str (not "int") to str

這裡我們放在try...except語法中,看其效果

try:
    print("start...")
    x = "12" + 12
    print("end...")
except Exception as ee:
    print("error: ",ee)

執行時輸出如下

start...
error:  can only concatenate str (not "int") to str

這裡分析以下其詳細步驟

  1. print("start...")成功執行
  2. x = "12" + 12報錯,停止繼續執行try管轄的程式碼(print("end...")沒有執行)
  3. 捕獲到異常,賦值給ee
  4. 執行print("error: ",ee)

3 丟擲異常

基礎語法

上面介紹了捕獲異常,下面來了解下如何丟擲異常。
這個常和try...expect配合使用。
一拋一接。

丟擲異常的語法非常簡單:

raise Exception()

raise可以理解為丟擲的意思。

其執行效果如下

Traceback (most recent call last):
  File "H:\github projects\big-shuang-python-introductory-course\codes\course7\demo503.py", line 1, in <module>
    raise Exception()
Exception

加資訊

我們也可以在丟擲的異常中加入一些說明資訊
比如

raise Exception("This is a base exception")

其執行效果如下

Traceback (most recent call last):
  File "H:\github projects\big-shuang-python-introductory-course\codes\course7\demo503.py", line 1, in <module>
    raise Exception("This is a base exception")
Exception: This is a base exception

自定義

不僅如此,我們還可以自定義異常類。
如下

class SimpleError(Exception):
    pass

raise SimpleError("Oh")

其執行效果如下

Traceback (most recent call last):
  File "H:\github projects\big-shuang-python-introductory-course\codes\course7\demo503.py", line 5, in <module>
    raise SimpleError("Oh")
__main__.SimpleError: Oh

4 拓展進階

用的很少,簡單瞭解就行。(我基本沒怎麼用過這些)

except拓展

接下來詳細介紹下except語法
except Exception這一句,會捕獲所有異常。
其實except也可以捕獲特定異常。
比如要捕獲TypeError
可以寫為except TypeError

也就是except後面跟的是要捕獲的異常類。
一個try語句可以接多個except語句,就像一個if後面可以接多個elif一樣。

try:
    pass # statement1
except TypeError as e1:
    pass # statement 2
except ValueError as e2:
    pass # statement 3
except Exception as e2:
    pass # statement 3

finally子句

try:
    pass # statement1
except Exception:
    pass # statement2
finally:
    pass # statement3

不管try管轄的程式碼是否引發錯誤,
finally管轄的程式碼永遠會被執行。