1. 程式人生 > Python進階應用教學 >11 Python 中的錯誤和異常

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
  • 在第 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 使用者程式碼生成的警告