# Python 異常處理
> 原文: [https://thepythonguru.com/python-exception-handling/](https://thepythonguru.com/python-exception-handling/)
* * *
于 2020 年 1 月 7 日更新
* * *
異常處理使您能夠優雅地處理錯誤并對其進行有意義的處理。 如果未找到所需文件,則向用戶顯示一條消息。 Python 使用`try`和`except`塊處理異常。
**語法**:
```py
try:
? ? # write some code
? ? # that might throw exception
except <ExceptionType>:
? ? # Exception handler, alert the user
```
如您在`try`塊中看到的那樣,您需要編寫可能引發異常的代碼。 當發生異常時,將跳過`try`塊中的代碼。 如果`except`子句中存在匹配的異常類型,則執行其處理器。
讓我們舉個例子:
```py
try:
? ? f = open('somefile.txt', 'r')
? ? print(f.read())
? ? f.close()
except IOError:
? ? print('file not found')
```
上面的代碼如下:
1. 執行`try`和`except`塊之間的第一條語句。
2. 如果沒有異常發生,則將跳過`except`子句下的代碼。
3. 如果文件不存在,則會引發異常,并且`try`塊中的其余代碼將被跳過
4. 發生異常時,如果異常類型與`except`關鍵字后的異常名稱匹配,則將執行該`except`子句中的代碼。
**注意**:
上面的代碼僅能處理`IOError`異常。 要處理其他類型的異常,您需要添加更多的`except`子句。
`try`語句可以具有多個`except`子句,也可以具有可選的`else`和/或`finally`語句。
```py
try:
? ? <body>
except <ExceptionType1>:
? ? <handler1>
except <ExceptionTypeN>:
? ? <handlerN>
except:
? ? <handlerExcept>
else:
? ? <process_else>
finally:
? ? <process_finally>
```
`except`子句類似于`elif`。 發生異常時,將檢查該異常以匹配`except`子句中的異常類型。 如果找到匹配項,則執行匹配大小寫的處理器。 另請注意,在最后的`except`子句中,`ExceptionType`被省略。 如果異常不匹配最后一個`except`子句之前的任何異常類型,則執行最后一個`except`子句的處理器。
**注意**:
`else`子句下的語句僅在沒有引發異常時運行。
**注意**:
無論是否發生異常,`finally`子句中的語句都將運行。
現在舉個例子。
```py
try:
? ? num1, num2 = eval(input("Enter two numbers, separated by a comma : "))
? ? result = num1 / num2
? ? print("Result is", result)
except ZeroDivisionError:
? ? print("Division by zero is error !!")
except SyntaxError:
? ? print("Comma is missing. Enter numbers separated by comma like this 1, 2")
except:
? ? print("Wrong input")
else:
? ? print("No exceptions")
finally:
? ? print("This will execute no matter what")
```
**注意**:
`eval()`函數允許 python 程序在其內部運行 python 代碼,`eval()`需要一個字符串參數。
要了解有關`eval()`的更多信息,請訪問 Python 中的[`eval()`](/python-builtin-functions/eval/)。
## 引發異常
* * *
要從您自己的方法引發異常,您需要像這樣使用`raise`關鍵字
```py
raise ExceptionClass("Your argument")
```
讓我們舉個例子
```py
def enterage(age):
? ? if age < 0:
? ? ? ? raise ValueError("Only positive integers are allowed")
? ? if age % 2 == 0:
? ? ? ? print("age is even")
? ? else:
? ? ? ? print("age is odd")
try:
? ? num = int(input("Enter your age: "))
? ? enterage(num)
except ValueError:
? ? print("Only positive integers are allowed")
except:
? ? print("something is wrong")
```
運行程序并輸入正整數。
**預期輸出**:
```py
Enter your age: 12
age is even
```
再次運行該程序并輸入一個負數。
**預期輸出**:
```py
Enter your age: -12
Only integers are allowed
```
## 使用異常對象
* * *
現在您知道如何處理異常,在本節中,我們將學習如何在異常處理器代碼中訪問異常對象。 您可以使用以下代碼將異常對象分配給變量。
```py
try:
? ? # this code is expected to throw exception
except ExceptionType as ex:
? ? # code to handle exception
```
如您所見,您可以將異常對象存儲在變量`ex`中。 現在,您可以在異常處理器代碼中使用此對象。
```py
try:
? ? number = eval(input("Enter a number: "))
? ? print("The number entered is", number)
except NameError as ex:
? ? print("Exception:", ex)
```
運行程序并輸入一個數字。
**預期輸出**:
```py
Enter a number: 34
The number entered is 34
```
再次運行程序并輸入一個字符串。
**預期輸出**:
```py
Enter a number: one
Exception: name 'one' is not defined
```
## 創建自定義異常類
* * *
您可以通過擴展`BaseException`類或`BaseException`的子類來創建自定義異常類。

如您所見,python 中的大多數異常類都是從`BaseException`類擴展而來的。 您可以從`BaseException`類或`BaseException`的子類(例如`RuntimeError`)派生自己的異常類。
創建一個名為`NegativeAgeException.py`的新文件,并編寫以下代碼。
```py
class NegativeAgeException(RuntimeError):
? ? def __init__(self, age):
? ? ? ? super().__init__()
? ? ? ? self.age = age
```
上面的代碼創建了一個名為`NegativeAgeException`的新異常類,該異常類僅由使用`super().__init__()`調用父類構造器并設置`age`的構造器組成。
## 使用自定義異常類
* * *
```py
def enterage(age):
? ? if age < 0:
? ? ? ? raise NegativeAgeException("Only positive integers are allowed")
? ? if age % 2 == 0:
? ? ? ? print("age is even")
? ? else:
? ? ? ? print("age is odd")
try:
? ? num = int(input("Enter your age: "))
? ? enterage(num)
except NegativeAgeException:
? ? print("Only positive integers are allowed")
except:
? ? print("something is wrong")
```
在下一篇文章中,我們將學習 [Python 模塊](/python-modules/)。
* * *
* * *
- 初級 Python
- python 入門
- 安裝 Python3
- 運行 python 程序
- 數據類型和變量
- Python 數字
- Python 字符串
- Python 列表
- Python 字典
- Python 元組
- 數據類型轉換
- Python 控制語句
- Python 函數
- Python 循環
- Python 數學函數
- Python 生成隨機數
- Python 文件處理
- Python 對象和類
- Python 運算符重載
- Python 繼承與多態
- Python 異常處理
- Python 模塊
- 高級 Python
- Python *args和**kwargs
- Python 生成器
- Python 正則表達式
- 使用 PIP 在 python 中安裝包
- Python virtualenv指南
- Python 遞歸函數
- __name__ == "__main__"是什么?
- Python Lambda 函數
- Python 字符串格式化
- Python 內置函數和方法
- Python abs()函數
- Python bin()函數
- Python id()函數
- Python map()函數
- Python zip()函數
- Python filter()函數
- Python reduce()函數
- Python sorted()函數
- Python enumerate()函數
- Python reversed()函數
- Python range()函數
- Python sum()函數
- Python max()函數
- Python min()函數
- Python eval()函數
- Python len()函數
- Python ord()函數
- Python chr()函數
- Python any()函數
- Python all()函數
- Python globals()函數
- Python locals()函數
- 數據庫訪問
- 安裝 Python MySQLdb
- 連接到數據庫
- MySQLdb 獲取結果
- 插入行
- 處理錯誤
- 使用fetchone()和fetchmany()獲取記錄
- 常見做法
- Python:如何讀取和寫入文件
- Python:如何讀取和寫入 CSV 文件
- 用 Python 讀寫 JSON
- 用 Python 轉儲對象