11 Python 中的錯誤和異常
Python 程式的執行過程中,當發生錯誤時會引起一個事件,該事件被稱為異常。例如:
- 如果程式中有語法錯誤,會產生 SyntaxError 型別的異常
- 執行除以 0 的運算,會產生 ZeroDivisionError 型別的異常
- 開啟一個不存在的檔案,會產生 IOError 型別的異常
程式設計中常見的異常型別總結如下:
異常名稱 | 描述 |
---|---|
ZeroDivisionError | 除(或取模)零 |
AssertionError | 斷言語句失敗 |
AttributeError | 物件沒有這個屬性 |
FileNotFoundError | 檔案不存在 |
ModuleNotFoundError | 模組不存在 |
IndexError | 序列中沒有此索引(index) |
KeyError | 對映中沒有這個鍵 |
NameError | 未宣告/初始化物件 |
SyntaxError | Python |
IndentationError | 縮排錯誤 |
1. ZeroDivisionError 的出現場景
進行除法運算時,要求被除數不能是 0,如果被除數是 0,則會產生異常,示例程式碼如下:
>>> 100 / 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
- 在第 4 行,因為被除數是 0,產生 ZeroDivisionError 型別的異常
2. AssertionError 的出現場景
編寫程式碼時,常常需要在某些特定的位置做出一些假設,假設某些條件為真,Python 使用 assert 語句假設指定條件為真:
assert 布林表示式
如果布林表示式為真,assert 語句不做任何事情;如果布林表示式為假,assert 語句丟擲 AssertionError 型別的異常。
編寫一個程式 AssertionError.py,功能是計算列表前 n 項元素之和:
def calcSum(list, n):
assert n <= len(list)
sum = 0
for i in range(n):
sum += list[i]
print('sum = %d' % sum)
list = [11, 22, 33, 44]
calcSum(list, 3)
calcSum(list, 5)
- 在第 1 行,calcSum 計算列表 list 的前 n 項之和
- 在第 2 行,使用 assert 語句驗證引數 n 是否小於等於 list 的長度
- 正常情況下,n 是小於等於 list 的長度
- 如果 n 大於 list 的長度,則表示輸入引數 n 有錯誤
- 在第 9 行,建立一個長度為 4 的列表
- 在第 10 行,傳遞引數 n 等於 3,是一個合法的引數
- 在第 11 行,傳遞引數 n 等於 5,是一個非法的引數
程式輸出結果如下:
sum = 66
Traceback (most recent call last):
File "AssertionError.py", line 11, in <module>
calcSum(list, 5)
File "AssertionError.py", line 2, in calcSum
assert n <= len(list)
AssertionError
- 在第 1 行,輸出 sum = 66
- calc(sum, 3) 計算列表前 3 項
- 結果為 66
- 在第 7 行,輸出 AssertionError
- calc(sum, 5) 計算列表前 5 項
- 列表只有 4 項元素
- 產生 AssertionError 型別的異常
3. AttributeError 的出現場景
Python 使用 object.property 的形式訪問物件的屬性,如果沒有定義指定名稱的屬性,則會丟擲 AttributeError 型別的異常。
編寫程式 AttributeError.py,程式定義了類 Person,Person 包含有兩個屬性:name 和 age,程式碼如下:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
tom = Person('tom', 10)
print(tom.name)
print(tom.age)
print(tom.address)
- 在第 1 行,定義類 Person,Person 包含有兩個屬性:name 和 age;
- 在第 6 行,例項化建立一個物件 tom;
- 屬性 name 為 ‘tom’;
- 屬性 age 為 10;
- 在第 7 行,訪問屬性 name ;
- 在第 8 行,訪問屬性 age;
- 在第 9 行,訪問屬性 address,在類 Person 中沒有定義該屬性。
程式輸出結果如下:
tom
10
Traceback (most recent call last):
File "AttributeError.py", line 9, in <module>
print(tom.address)
AttributeError: 'Person' object has no attribute 'address'
- 在第 1 行,輸出屬性 name 的值;
- 在第 2 行,輸出屬性 age 的值;
- 在第 1 行,屬性 address 不存在,產生 AttributeError 型別的異常。
4. FileNotFoundError 的出現場景
python 使用函式 open(path) 開啟指定路徑的檔案,如果檔案不存在,則產生 FileNotFoundError 型別的異常,示例如下:
>> open('non-exist-file')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'non-exist-file'
- 在第 4 行,因為檔案 non-exist-file 不存在,產生 FileNotFoundError 型別的異常。
5. ModuleNotFoundError 的出現場景
python 使用關鍵字 import module_name 開啟匯入名稱的模組,如果模組不存在,則產生 ModuleNotFoundError 型別的異常,示例如下:
>>> import non_exist_module
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'non_exist_module'
- 在第 4 行,因為模組 non_exist_file 不存在,產生 ModuleNotFoundError 型別的異常
6. IndexError 的出現場景
在 Python 使用 list[index] 的形式訪問列表 list 的指定位置的元素,要求 index:
- 大於等於 0
- 小於列表的長度
如果 index 不在合法範圍,則產生 IndexError 型別的異常。
>>> list = ['www', 'imooc', 'com']
>>> list[3]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
- 在第 1 行,建立長度為 3 的列表;
- 合法的 index 是 0、1、2;
- 在第 2 行,index 不在合法範圍;
- 在第 5 行,產生 IndexError 型別的異常。
7. NameError 的出現場景
Python 在讀取變數時,要求變數必須已經定義。如果讀取一個尚未定義的變數,會產生 NameError 型別的異常。
>>> variable = 123
>>> print(varible)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'varible' is not defined
- 在第 1 行,建立變數 variable;
- 在第 2 行,此處將 variable 錯誤的拼寫成 varible;
- 變數 varible 還沒有建立;
- 在第 5 行,產生 NameError 型別的異常。
8. SyntaxError 的出現場景
Python 程式中出現語法錯誤時,會產生 SyntaxError 型別的異常。編寫程式 SyntaxError.py:
if 2>1
print('2>1 is True')
print('2>1 is False')
- 在第 1 行,有一處語法錯誤,在行尾缺少冒號 :
程式輸出結果如下:
File "SyntaxError.py", line 1
if 2>1
^
SyntaxError: invalid syntax
- 在第 1 行,File “SyntaxError.py”, line 1
- 指明錯誤在檔案 SyntaxError.py 中的第 1 行
- 在第 4 行,產生 SyntaxError 型別的異常
9. IndentationError 的出現場景
Python 程式中出現縮排的語法錯誤時,會產生 IndentationError 型別的異常。編寫程式 IndentationError.py:
if 2>1:
print('2>1 is True')
print('2>1 is False')
- 在第 2 行,縮排為 4 個空格
- 在第 3 行,縮排為 2 個空格
程式輸出結果如下:
File "IndentationError.py", line 3
print('2>1 is False')
^
IndentationError: unindent does not match any outer indentation level
- 在第 4 行,輸出 IndentationError;
- 源程式第 2 行的縮排為 2 個空格;
- 源程式第 3 行的縮排為 4 個空格;
- 兩者不匹配,產生 IndentationError 型別的異常。
11. Python 的標準異常型別總結
在上面的小節中講解了常見的異常型別,Python 中全部的標準的異常型別如下:
異常名稱 | 描述 |
---|---|
SystemExit | 直譯器請求退出 |
KeyboardInterrupt | 使用者中斷執行(通常是輸入^C) |
Exception | 常規錯誤的基類 |
StopIteration | 迭代器沒有更多的值 |
GeneratorExit | 生成器(generator)發生異常來通知退出 |
StandardError | 所有的內建標準異常的基類 |
ArithmeticError | 所有數值計算錯誤的基類 |
FloatingPointError | 浮點計算錯誤 |
OverflowError | 數值運算超出最大限制 |
ZeroDivisionError | 除(或取模)零 |
AssertionError | 斷言語句失敗 |
AttributeError | 物件沒有這個屬性 |
EOFError | 沒有內建輸入,到達EOF |
EnvironmentError | 作業系統錯誤的基類 |
IOError | 輸入/輸出操作失敗 |
OSError | 作業系統錯誤 |
WindowsError | 系統呼叫失敗 |
ImportError | 匯入模組/物件失敗 |
LookupError | 無效資料查詢的基類 |
IndexError | 序列中沒有此索引(index) |
KeyError | 對映中沒有這個鍵 |
MemoryError | 記憶體溢位錯誤(對於Python |
NameError | 未宣告/初始化物件 |
UnboundLocalError | 訪問未初始化的本地變數 |
ReferenceError | 弱引用(Weak |
RuntimeError | 一般的執行時錯誤 |
NotImplementedError | 尚未實現的方法 |
SyntaxError | Python |
IndentationError | 縮排錯誤 |
TabError | Tab |
SystemError | 一般的直譯器系統錯誤 |
TypeError | 對型別無效的操作 |
ValueError | 傳入無效的引數 |
UnicodeError | Unicode |
UnicodeDecodeError | Unicode |
UnicodeEncodeError | Unicode |
UnicodeTranslateError | Unicode |
DeprecationWarning | 關於被棄用的特徵的警告 |
FutureWarning | 關於構造將來語義會有改變的警告 |
OverflowWarning | 舊的關於自動提升為長整型(long)的警告 |
PendingDeprecationWarning | 關於特性將會被廢棄的警告 |
RuntimeWarning | 可疑的執行時行為(runtime |
SyntaxWarning | 可疑的語法的警告 |
UserWarning | 使用者程式碼生成的警告 |