FishC筆記—33 講 異常處理:你不可能總是對的2

本期內容詳解:
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()  
發佈了89 篇原創文章 · 獲贊 316 · 訪問量 41萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章