Python 中的錯誤和異常
Python 程序的執(zhí)行過程中,當(dāng)發(fā)生錯誤時會引起一個事件,該事件被稱為異常。例如:
- 如果程序中有語法錯誤,會產(chǎn)生 SyntaxError 類型的異常
- 執(zhí)行除以 0 的運算,會產(chǎn)生 ZeroDivisionError 類型的異常
- 打開一個不存在的文件,會產(chǎn)生 IOError 類型的異常
編程中常見的異常類型總結(jié)如下:
異常名稱 | 描述 |
---|---|
ZeroDivisionError | 除(或取模)零 |
AssertionError | 斷言語句失敗 |
AttributeError | 對象沒有這個屬性 |
FileNotFoundError | 文件不存在 |
ModuleNotFoundError | 模塊不存在 |
IndexError | 序列中沒有此索引(index) |
KeyError | 映射中沒有這個鍵 |
NameError | 未聲明/初始化對象 |
SyntaxError | Python |
IndentationError | 縮進(jìn)錯誤 |
1. ZeroDivisionError 的出現(xiàn)場景
進(jìn)行除法運算時,要求被除數(shù)不能是 0,如果被除數(shù)是 0,則會產(chǎn)生異常,示例代碼如下:
>>> 100 / 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
- 在第 4 行,因為被除數(shù)是 0,產(chǎn)生 ZeroDivisionError 類型的異常
2. AssertionError 的出現(xiàn)場景
編寫代碼時,常常需要在某些特定的位置做出一些假設(shè),假設(shè)某些條件為真,Python 使用 assert 語句假設(shè)指定條件為真:
assert 布爾表達(dá)式
如果布爾表達(dá)式為真,assert 語句不做任何事情;如果布爾表達(dá)式為假,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 語句驗證參數(shù) n 是否小于等于 list 的長度
- 正常情況下,n 是小于等于 list 的長度
- 如果 n 大于 list 的長度,則表示輸入?yún)?shù) n 有錯誤
- 在第 9 行,創(chuàng)建一個長度為 4 的列表
- 在第 10 行,傳遞參數(shù) n 等于 3,是一個合法的參數(shù)
- 在第 11 行,傳遞參數(shù) n 等于 5,是一個非法的參數(shù)
程序輸出結(jié)果如下:
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 項
- 結(jié)果為 66
- 在第 7 行,輸出 AssertionError
- calc(sum, 5) 計算列表前 5 項
- 列表只有 4 項元素
- 產(chǎn)生 AssertionError 類型的異常
3. AttributeError 的出現(xiàn)場景
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 行,實例化創(chuàng)建一個對象 tom;
- 屬性 name 為 ‘tom’;
- 屬性 age 為 10;
- 在第 7 行,訪問屬性 name ;
- 在第 8 行,訪問屬性 age;
- 在第 9 行,訪問屬性 address,在類 Person 中沒有定義該屬性。
程序輸出結(jié)果如下:
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 不存在,產(chǎn)生 AttributeError 類型的異常。
4. FileNotFoundError 的出現(xiàn)場景
python 使用函數(shù) open(path) 打開指定路徑的文件,如果文件不存在,則產(chǎn)生 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 不存在,產(chǎn)生 FileNotFoundError 類型的異常。
5. ModuleNotFoundError 的出現(xiàn)場景
python 使用關(guān)鍵字 import module_name 打開導(dǎo)入名稱的模塊,如果模塊不存在,則產(chǎn)生 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 不存在,產(chǎn)生 ModuleNotFoundError 類型的異常
6. IndexError 的出現(xiàn)場景
在 Python 使用 list[index] 的形式訪問列表 list 的指定位置的元素,要求 index:
- 大于等于 0
- 小于列表的長度
如果 index 不在合法范圍,則產(chǎn)生 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 行,創(chuàng)建長度為 3 的列表;
- 合法的 index 是 0、1、2;
- 在第 2 行,index 不在合法范圍;
- 在第 5 行,產(chǎn)生 IndexError 類型的異常。
7. NameError 的出現(xiàn)場景
Python 在讀取變量時,要求變量必須已經(jīng)定義。如果讀取一個尚未定義的變量,會產(chǎn)生 NameError 類型的異常。
>>> variable = 123
>>> print(varible)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'varible' is not defined
- 在第 1 行,創(chuàng)建變量 variable;
- 在第 2 行,此處將 variable 錯誤的拼寫成 varible;
- 變量 varible 還沒有創(chuàng)建;
- 在第 5 行,產(chǎn)生 NameError 類型的異常。
8. SyntaxError 的出現(xiàn)場景
Python 程序中出現(xiàn)語法錯誤時,會產(chǎn)生 SyntaxError 類型的異常。編寫程序 SyntaxError.py:
if 2>1
print('2>1 is True')
print('2>1 is False')
- 在第 1 行,有一處語法錯誤,在行尾缺少冒號 :
程序輸出結(jié)果如下:
File "SyntaxError.py", line 1
if 2>1
^
SyntaxError: invalid syntax
- 在第 1 行,F(xiàn)ile “SyntaxError.py”, line 1
- 指明錯誤在文件 SyntaxError.py 中的第 1 行
- 在第 4 行,產(chǎn)生 SyntaxError 類型的異常
9. IndentationError 的出現(xiàn)場景
Python 程序中出現(xiàn)縮進(jìn)的語法錯誤時,會產(chǎn)生 IndentationError 類型的異常。編寫程序 IndentationError.py:
if 2>1:
print('2>1 is True')
print('2>1 is False')
- 在第 2 行,縮進(jìn)為 4 個空格
- 在第 3 行,縮進(jìn)為 2 個空格
程序輸出結(jié)果如下:
File "IndentationError.py", line 3
print('2>1 is False')
^
IndentationError: unindent does not match any outer indentation level
- 在第 4 行,輸出 IndentationError;
- 源程序第 2 行的縮進(jìn)為 2 個空格;
- 源程序第 3 行的縮進(jìn)為 4 個空格;
- 兩者不匹配,產(chǎn)生 IndentationError 類型的異常。
11. Python 的標(biāo)準(zhǔn)異常類型總結(jié)
在上面的小節(jié)中講解了常見的異常類型,Python 中全部的標(biāo)準(zhǔn)的異常類型如下:
異常名稱 | 描述 |
---|---|
SystemExit | 解釋器請求退出 |
KeyboardInterrupt | 用戶中斷執(zhí)行(通常是輸入^C) |
Exception | 常規(guī)錯誤的基類 |
StopIteration | 迭代器沒有更多的值 |
GeneratorExit | 生成器(generator)發(fā)生異常來通知退出 |
StandardError | 所有的內(nèi)建標(biāo)準(zhǔn)異常的基類 |
ArithmeticError | 所有數(shù)值計算錯誤的基類 |
FloatingPointError | 浮點計算錯誤 |
OverflowError | 數(shù)值運算超出最大限制 |
ZeroDivisionError | 除(或取模)零 |
AssertionError | 斷言語句失敗 |
AttributeError | 對象沒有這個屬性 |
EOFError | 沒有內(nèi)建輸入,到達(dá)EOF |
EnvironmentError | 操作系統(tǒng)錯誤的基類 |
IOError | 輸入/輸出操作失敗 |
OSError | 操作系統(tǒng)錯誤 |
WindowsError | 系統(tǒng)調(diào)用失敗 |
ImportError | 導(dǎo)入模塊/對象失敗 |
LookupError | 無效數(shù)據(jù)查詢的基類 |
IndexError | 序列中沒有此索引(index) |
KeyError | 映射中沒有這個鍵 |
MemoryError | 內(nèi)存溢出錯誤(對于Python |
NameError | 未聲明/初始化對象 |
UnboundLocalError | 訪問未初始化的本地變量 |
ReferenceError | 弱引用(Weak |
RuntimeError | 一般的運行時錯誤 |
NotImplementedError | 尚未實現(xiàn)的方法 |
SyntaxError | Python |
IndentationError | 縮進(jìn)錯誤 |
TabError | Tab |
SystemError | 一般的解釋器系統(tǒng)錯誤 |
TypeError | 對類型無效的操作 |
ValueError | 傳入無效的參數(shù) |
UnicodeError | Unicode |
UnicodeDecodeError | Unicode |
UnicodeEncodeError | Unicode |
UnicodeTranslateError | Unicode |
DeprecationWarning | 關(guān)于被棄用的特征的警告 |
FutureWarning | 關(guān)于構(gòu)造將來語義會有改變的警告 |
OverflowWarning | 舊的關(guān)于自動提升為長整型(long)的警告 |
PendingDeprecationWarning | 關(guān)于特性將會被廢棄的警告 |
RuntimeWarning | 可疑的運行時行為(runtime |
SyntaxWarning | 可疑的語法的警告 |
UserWarning | 用戶代碼生成的警告 |