本期內容詳解:
Python標準異常總結
異常 | 說明 |
---|---|
AssertionError | 斷言語句(assert)失敗 |
AttributeError | 嘗試訪問未知的對象屬性 |
EOFError | 用戶輸入文件末尾標誌EOF(Ctrl+d) |
FloatingPointError | 浮點計算錯誤 |
GeneratorExit | Gengeator.close()方法被調用的時候 |
ImportError | 導入模塊失敗的時候 |
IndexError | 索引超出序列的範圍 |
KeyError | 字典中查找一個不存在的關鍵字 |
KeyboardError | 用戶輸入中斷鍵(Ctrl+c) |
MemoryError | 內存溢出(可通過刪除對象釋放內存) |
NameError | 嘗試訪問一個不存在的變量 |
NotImplementedError | 尚未實現的方法 |
OSError | 操作系統產生的異常(例如打開一個不存在的文件) |
OverflowError | 數值運算超出最大限制 |
ReferenceError | 弱引用(weak reference)試圖訪問一個已經被垃圾回收幾隻回收了的對象 |
RuntimeError | 一般的運行時錯誤 |
StopIteration | 迭代器沒有更多的值 |
SyntaxError | Python的語法錯誤 |
IndentationError | 縮進錯誤 |
TabError | Tab和空格混合使用 |
SystemError | Python編譯器系統錯誤 |
SystenExit | Python編譯器進程被關閉 |
TypeError | 不同類型間的無效操作 |
UnboundLocalError | 訪問一個未初始化的本地變量(NameError的子類) |
UnicodeError | Unicode相關的錯誤(ValueError的子類) |
UnicodeEncodeError | Unicode編碼時的錯誤(UnicodeError的子類) |
UnicodeDecodeError | Unicode解碼時的錯誤(UnicodeError的子類) |
UnicodeTranslateError | Unicode轉換時的錯誤(UnicodeError的子類) |
ValueError | 傳入無效的參數 |
ZeroDivisionError | 除數爲零 |
以下是 Python 內置異常類的層次結構:
典型課後題
結合你自身的編程經驗,總結下異常處理機制的重要性?
答:由於環境的不確定性和用戶操作的不可以預知性都可能導致程序出現各種問題,因此異常機制最重要的無非就是:
增強程序的健壯性和用戶體驗,儘可能的捕獲所有預知的異常並寫好處理的代碼,當異常出現的時候,程序自動消化並恢復正常(不至於崩潰)。
請問以下代碼是否會產生異常,如果會的話,請寫出異常的名稱:
>>> my_list = [1, 2, 3, 4,,]
答:語法錯誤SyntaxError: invalid syntax
請問以下代碼是否會產生異常,如果會的話,請寫出異常的名稱:
>>> my_list = [1, 2, 3, 4, 5]
>>> print(my_list[len(my_list)])
答:len(my_list) 是獲得列表的長度,這裏長度爲5,該列表各個元素的訪問索引號分別是:[0, 1, 2, 3, 4],因此試圖訪
問 my_list(5) 會引發 IndexError: list index out of range 異常。
請問以下代碼是否會產生異常,如果會的話,請寫出異常的名稱:
>>> my_list = [3, 5, 1, 4, 2]
>>> my_list.sorted()
答:初學者容易疏忽的錯誤,列表的排序方法叫 list.sort(),sorted() 是BIF。因此會引發 AttributeError: ‘list’ object
has no attribute ‘sorted’ 異常。
請問以下代碼是否會產生異常,如果會的話,請寫出異常的名稱:
>>> my_dict = {'host': 'http://bbs.fishc.com', 'port': '80'}
>>> print(my_dict['server'])
答:嘗試訪問字典中一個不存在的“鍵”引發 KeyError: ‘server’ 異常,爲了避免這個異常發生,可以使用 dict.get() 方法:
if not my_dict.get('server'):
print('您所訪問的鍵【server】不存在!')
請問以下代碼是否會產生異常,如果會的話,請寫出異常的名稱:
def my_fun(x, y):
print(x, y)
f(x=1, 2)
答:如果使用關鍵字參數的話,需要兩個參數均使用關鍵字參數 f(x=1, y=2)
請問以下代碼是否會產生異常,如果會的話,請寫出異常的名稱:
f = open('C:\\test.txt', wb)
f.write('I love FishC.com!\n')
f.close()
答:注意 open() 第二個參數是字符串,應該 f = open(‘C:\test.txt’, ‘wb’) 。wb不加雙引號 Python 還以爲是變量名呢,往上一找,艾瑪沒找着……引發 NameError 異常。由於打開文件失敗,接着下邊一連串與 f 相關的均會報同樣異常。
請問以下代碼是否會產生異常,如果會的話,請寫出異常的名稱:
def my_fun1():
x = 5
def my_fun2():
x *= x
return x
return my_fun2()
my_fun1()
答:閉包的知識大家還記得不? Python 認爲在內部函數的 x 是局部變量的時候,外部函數的 x 就被屏蔽了起來,所以執行 x *= x 的時候,在右邊根本就找不到局部變量 x 的值,因此報錯。
在 Python3 之前沒有直接的解決方案,只能間接地通過容器類型來存放,因爲容器類型不是放在棧裏,所以不會被“屏蔽”掉。容器類型這個詞兒大家是不是似曾相識?我們之前介紹的字符串、列表、元祖,這些啥都可以往裏的扔的就是容器類型啦。
於是乎我們可以把代碼改造爲:
def my_fun1():
x = [5]
def my_fun2():
x[0] *= x[0]
return x[0]
return my_fun2()
my_fun1()
但是到了 Python3 的世界裏,又有了不少的改進,如果我們希望在內部函數裏可以修改外部函數裏的局部變量的值,
那麼也有一個關鍵字可以使用,就是 nonlocal:
def my_fun1():
x = 5
def my_fun2():
nonlocal x
x *= x
return x
return my_fun2()
my_fun1()