本期內容詳解:
try語句:
try:
檢測範圍
except Exception[as reason]:
出現異常(Exception)後的處理代碼
try-finally語句:
try:
檢測範圍
except Exception[as reason]:
出現異常(Exception)後的處理代碼
finally:
無論如何都會被執行的代碼
raise語句:
raise 異常的名字
>>> raise ZeroDivisionError('除數爲零的異常')
<span style="color:#ff0000;">Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
raise ZeroDivisionError('除數爲零的異常')
ZeroDivisionError: 除數爲零的異常</span>
>>>
典型課後題
我們使用什麼方法來處理程序中出現的異常?`
答:使用 try……except 搭配來捕獲處理程序中出現的異常。
try:
檢測範圍來自:bbs.fishc.com
except Exception[as reason]:
出現異常(Exception)後的處理代碼
一個 try 語句可以和多個 except 語句搭配嗎?爲什麼?
答:可以。因爲 try 語句塊中可能出現多類異常,利用多個 except 語句可以分別捕獲並處理我們感興趣的異常。
try:
sum = 1 + '1'
f = open('我是一個不存在的文檔.txt')
print(f.read())
f.close()
except OSError as reason:
print('文件出錯啦T_T\n錯誤原因是:' + str(reason))
except TypeError as reason:
print('類型出錯啦T_T\n錯誤原因是:' + str(reason))
你知道如何統一處理多類異常嗎?
答:在 except 後邊使用小括號“()”把多個需要統一處理的異常括起來:
try:
int('abc')
sum = 1 + '1'
f = open('我是一個不存在的文檔.txt')
print(f.read())
f.close()
except (OSError, TypeError):
print('出錯啦T_T\n錯誤原因是:' + str(reason))
except 後邊如果不帶任何異常類,Python 會捕獲所有(try 語句塊內)的異常並統一處理,但小甲魚卻不建議這麼做,你知道爲什麼嗎?
答:因爲它會隱藏所有程序員未想到並且未做好準備處理的錯誤,例如用戶輸入ctrl+c試圖終止程序會被解釋爲KeyboardInterrupt異常。
如果異常發生在成功打開文件後,Python 跳到 except 語句執行,並沒有執行關閉文件的命令(用戶寫入文件的數據就可能沒有保存起來),因此我們需要確保無論如何(就算出了異常退出)文件也要被關閉,我們應該怎麼做呢?
答:我們可以使用 finally 語句來實現,如果 try 語句塊中沒有出現任何運行時錯誤,會跳過 except 語句塊執行 finally語句塊的內容。
如果出現異常,則會先執行 except 語句塊的內容再接着執行 finally 語句塊的內容。總之,finally 語句塊裏的內容就是確保無論如何都將被執行的內容!
請恢復以下代碼中馬賽克擋住的內容,使得程序執行後可以按要求輸出。
代碼:
輸出:
參考答案:
try:
for i in range(3):
for j in range(3):
if i == 2:
raise KeyboardInterrupt
print(i, j)
except KeyboardInterrupt:
print('退出啦!')
還記得我們第一個小遊戲嗎?只要用戶輸入非整型數據,程序立刻就會蹦出不和諧的異常信息然後崩潰。請使用剛學的異常處理方法修改以下程序,提高用戶體驗。)
答:這裏對可能導致異常的 guess = int(temp) 進行監測
import random
secret = random.randint(1,10)
print('------------------我愛魚C工作室------------------')
temp = input("不妨猜一下小甲魚現在心裏想的是哪個數字:")
try:
guess = int(temp)
except ValueError:
print('輸入錯誤!')
guess = secret
while guess != secret:
temp = input("哎呀,猜錯了,請重新輸入吧:")
guess = int(temp)
if guess == secret:
print("我草,你是小甲魚心裏的蛔蟲嗎?!")
print("哼,猜中了也沒有獎勵!")
else:
if guess > secret:
print("哥,大了大了~~~")
else:
print("嘿,小了,小了~~~")
print("遊戲結束,不玩啦^_^")
input() 函數有可能產生兩類異常:EOFError(文件末尾endoffile,當用戶按下組合鍵 Ctrl+d 產生)和 KeyboardInterrupt(取消輸入,當用戶按下組合鍵 Ctrl+c 產生),再次修改上邊代碼,捕獲處理 input() 的兩類異常,提高用戶體驗。
import random
secret = random.randint(1,10)
print('------------------我愛魚C工作室------------------')
try:
temp = input("不妨猜一下小甲魚現在心裏想的是哪個數字:")
guess = int(temp)
except (ValueError, EOFError, KeyboardInterrupt):
print('輸入錯誤!')
guess = secret
while guess != secret:
temp = input("哎呀,猜錯了,請重新輸入吧:")
guess = int(temp)
if guess == secret:
print("我草,你是小甲魚心裏的蛔蟲嗎?!")
print("哼,猜中了也沒有獎勵!")
else:
if guess > secret:
print("哥,大了大了~~~")
else:
print("嘿,小了,小了~~~")
print("遊戲結束,不玩啦^_^")
嘗試一個新的函數 int_input(),當用戶輸入整數的時候正常返回,否則提示出錯並要求重新輸入。
程序實現如圖:
def int_input(prompt=''):
while True:
try:
int(input(prompt))
break
except ValueError:
print('出錯,您輸入的不是整數!')
int_input('請輸入一個整數:')
把文件關閉放在 finally 語句塊中執行還是會出現問題,像下邊這個代碼,當前文件夾中並不存在”My_File.txt”這個文件,那麼程序執行起來會發生什麼事情呢?你有辦法解決這個問題嗎?
try:
f = open('My_File.txt') # 當前文件夾中並不存在"My_File.txt"這個文件T_T
print(f.read())
except OSError as reason:
print('出錯啦:' + str(reason))
finally:
f.close()
答:由於finally語句塊裏試圖去關閉一個並沒有成功打開的文件,因此會彈出錯誤內容如下:
>>> 出錯啦:[Errno 2] No such file or directory: 'My_File.txt'
Traceback (most recent call last):
File "C:\Users\FishC000\Desktop\test.py", line 7, in <module>
f.close()
NameError: name 'f' is not defined
我們這麼修正:
try:
f = open('My_File.txt') # 當前文件夾中並不存在"My_File.txt"這個文件T_T
print(f.read())
except OSError as reason:
print('出錯啦:' + str(reason))
finally:
if 'f' in locals(): # 如果文件對象變量存在當前局部變量符號表的話,說明打開成功
f.close()