天天看點

python 異常

導航:

1、文法錯誤

2、異常

3、異常處理

4、異常的傳遞

5、抛出異常

6、在異常進行中抛出異常

python的異常分為兩種,1)、文法錯誤,在python解釋器的文法檢測中不通過不能運作代碼    2)、異常,python程式運作期檢測到的錯誤被稱為異常。在沒有做異常處理時,将終止程式并提示異常資訊,如:①字元串轉換為數字時的類型轉換異常,②檔案讀取時的檔案不存在異常,③網絡連結時主機不可達異常···等。當Python腳本發生異常時我們需要捕獲處理它,否則程式會終止執行。畢竟誰也不希望用着的程式突然的就崩了

python的文法錯誤是很多初學者經常遇到的一個問題,這類錯誤比較低級,隻要多敲幾遍代碼就可以減少這樣的錯誤

1 >>> if Trur
 2   File "<stdin>", line 1
 3     if Trur
 4           ^
 5 SyntaxError: invalid syntax
 6 >>> print("as"))
 7   File "<stdin>", line 1
 8     print("as"))
 9                ^
10 SyntaxError: invalid syntax      

如:出現這樣的錯誤就是文法錯誤,第1行結尾if語句缺少 ":",第6行結尾多了 ")" 

1)運作期檢測到的錯誤被稱為異常,python的文法檢測無法檢查這樣的錯誤。

1 >>> int("aa")
2 Traceback (most recent call last):
3   File "<stdin>", line 1, in <module>
4 ValueError: invalid literal for int() with base 10: 'aa'
5 >>> f = open("aaa.txt","r")
6 Traceback (most recent call last):
7   File "<stdin>", line 1, in <module>
8 FileNotFoundError: [Errno 2] No such file or directory: 'aaa.txt'      

其中第1行,第5行都是出現異常的地方,看一下異常的輸出資訊,如下圖

python 異常

2)python的标準異常類

BaseException 為所有異常的基類,Exception 為正常錯誤的基類

其它python的異常類可以到這裡看(http://www.runoob.com/python/python-exceptions.html),就不再一一的述說,也可以百度檢視

為了提高程式的健壯性,不讓程式出現異常時出現崩潰的情況,在必要時需要進行異常處理

1)try-except:語句

①、最簡單的異常處理語句如下,當try的語句塊中有異常出現時,下邊的的語句将不再執行(第3行),異常被except捕獲,執行except中的語句塊後繼續向下執行程式(如第6行)。注:except後邊不跟異常的類型,預設捕捉所有的異常

1 try:
 2     int("aaa")
 3     print("---aaa---")
 4 except:
 5     print("出現異常-->英文字母不能轉換為數字")
 6 print("----------")
 7 
 8 
 9 # 輸出結果
10 出現異常-->英文字母不能轉換為數字
11 ----------      

②、多分支異常,當我們需要捕獲不同的異常時可以用多個except來實作,需要擷取異常的資訊可通過as 變量名得到異常的對象,如第7行

1 try:
 2     nu = int("100")
 3     print("轉換後的值nu:", nu)
 4     i = 1 / 0
 5 except ValueError:
 6     print("出現異常-->英文字母不能轉換為數字")
 7 except ZeroDivisionError as e:  # 通過 as 變量名 擷取異常的對象
 8     print("出現異常-->除數不能為零")
 9     print("異常的提示資訊-->", e)
10 except:
11     pass
12 print("----------")
13 
14 
15 # 輸出結果
16 轉換後的值nu: 100
17 出現異常-->除數不能為零
18 異常的提示資訊--> division by zero
19 ----------      

③、當我們需要将多個異常按相同的處理方式可以使用  except (ValueError, [ZeroDivisionError [, NameError]]):

1 try:
 2     i = 1 / 0
 3     nu = int("aa")
 4 except (ValueError, ZeroDivisionError) as e:
 5     print(e)
 6 except:
 7     pass
 8 print("----------")
 9 
10 
11 # 輸出結果
12 division by zero
13 ----------      

2)try-except-else-finally 語句

①、當try-except-else-finally中出現了finally語句,不管是否出現異常finally語句塊中的語句一定會執行,而else中的語句隻有不出現異常是才會執行

出現異常時try-except-else-finally如下

1 try:
 2     i = 1 / 0
 3     print("沒有出現異常i值", i)
 4 except Exception as e:
 5     print("出現異常-->", e)
 6 else:
 7     print("沒有出現異常-->執行else")
 8 finally:
 9     print("不管是否出現異常,這裡的語句一定會被執行")
10 
11 
12 # 輸出結果
13 出現異常--> division by zero
14 不管是否出現異常,這裡的語句一定會被執行      

沒有出現異常時try-except-else-finally如下

1 try:
 2     i = 1 / 1
 3     print("沒有出現異常i值", i)
 4 except Exception as e:
 5     print("出現異常-->", e)
 6 else:
 7     print("沒有出現異常-->執行else")
 8 finally:
 9     print("不管是否出現異常,這裡的語句一定會被執行")
10 
11 
12 # 輸出結果
13 沒有出現異常i值 1.0
14 沒有出現異常-->執行else
15 不管是否出現異常,這裡的語句一定會被執行      

②、try-except-else-finally還可以拆開使用,有三種形式 1)try-except-finally   2)try-except-else    3)try-finally。  這裡就不展示代碼了

在發生異常的語句中沒有處理異常的語句,異常将向上層傳遞,直到遇到處理異常的語句,或python解釋器終止程式

1 def test2():
 2     int("aa")
 3 
 4 def test1():
 5     test2()
 6 
 7 try:
 8     test1()
 9 except Exception as e:
10     print(e)
11 print("-----------")
12 
13 
14 # 輸出結果
15 invalid literal for int() with base 10: 'aa'
16 -----------      

如上test2中第2行出現異常,将向第5行調用test2的語句處傳遞,這裡依舊沒有異常處理語句,将繼續往上層傳遞到第8行處被except捕獲

5、抛出異常 raise

1)抛出python已定義的異常

通過raise 異常類型即可抛出一個異常,抛出的異常也會被except捕獲到。如下邊第4行

1 age = 500
 2 try:
 3     if age < 0 or age > 200:
 4         raise ValueError("age範圍0-200")
 5     print("age", age)
 6 except ValueError as e:
 7     print("出現異常-->", e)
 8 
 9 
10 # 輸出結果
11 出現異常--> age範圍0-200      

2)抛出自定義異常

抛出自定義異常首先得有個自定義的異常類,注:自定義的異常必須直接或間接的繼承Exception基類

1 class MyException(Exception):  # 自定義異常類
 2     def __init__(self, msg):
 3         self.msg = msg
 4 
 5 
 6 age = 500
 7 try:
 8     if age < 0 or age > 200:
 9         raise MyException("age範圍0-200")  # 抛出自定義異常
10     print("age", age)
11 except MyException as e:
12     print("出現異常-->", e)
13 
14 
15 # 輸出結果
16 出現異常--> age範圍0-200      

當然自定義異常類也可以擁有許多的功能,就得看需求添加啦

 6、在異常進行中抛出異常 

 有某需求:當捕獲到異常時處理完後想繼續抛出異常.....

在except中用raise可以抛出目前異常

1 try:
 2     i = 1 / 0  # 異常的語句
 3 except Exception as e:
 4     print("出現異常-->", e)
 5     raise  # 處理完後繼續抛出異常,raise表示抛出目前異常
 6 print("-------------")
 7 
 8 
 9 # 輸出結果
10 出現異常--> division by zero
11 Traceback (most recent call last):
12   File "<stdin>", line 2, in <module>
13     i = 1 / 0
14 ZeroDivisionError: division by zero      

注:異常處理盡量在需要的時候再使用,使用太多會影響代碼的可讀性

繼續閱讀