2020年9月16日星期三

[課後作業] 第033講:異常處理:你不可能總是對的2 |課後測試題及答案

[課後作業] 第033講:異常處理:你不可能總是對的2 |課後測試題及答案




《零基礎入門學習Python》視頻下載地址:傳送門)


測試題:


0.我們使用什麼方法來處理程序中出現的異常?


1.一個try語句可以和多個except語句搭配嗎?為什麼?



2.你知道如何統一處理多類異常嗎?



3. except後邊如果不帶任何異常類, Python會捕獲所有(try語句塊內)的異常並統一處理,但小甲魚卻不建議這麼做,你知道為什麼嗎?



4.如果異常發生在成功打開文件後,Python跳到except語句執行,並沒有執行關閉文件的命令(用戶寫入文件的數據就可能沒有保存起來),因此我們需要確保無論如何(就算出了異常退出)文件也要被關閉,我們應該怎麼做呢?



5.請恢復以下代碼中馬賽克擋住的內容,使得程序執行後可以按要求輸出。


代碼:Powered by bbs.fishc.com

Jn({ZUA"tcP3^*MKF+!g#L7kC_
輸出:版權屬於:bbs.fishc.com

)&Nu|f<(5GqoxtpPeD$d
{y_&FT90bjeV;pis$UlZo<6
動動手:
#8wV*QdE@"_{lnT t6H`sS;-IA&N2C
0.還記得我們第一個小遊戲嗎?只要用戶輸入非整型數據,程序立刻就會蹦出不和諧的異常信息然後崩潰。請使用剛學的異常處理方法修改以下程序,提高用戶體驗。.j7Av`@lw
<WsJ7wUDf8T$ F^Z3;->B
猜數字小遊戲:
  1. import random

  2. secret = random.randint(1,10)
  3. print('------------------我愛魚C工作室------------------')
  4. temp = input("不妨猜一下小甲魚現在心裡想的是哪個數字:")
  5. guess = int(temp)
  6. while guess != secret:
  7.     temp = input("哎呀,猜錯了,請重新輸入吧:")
  8.     guess = int(temp)
  9.     if guess == secret:
  10.         print("我草,你是小甲魚心裡的蛔蟲嗎?!")
  11.         print("哼,猜中了也沒有獎勵!")
  12.     else:
  13.         if guess > secret:
  14.             print("哥,大了大了~~~")
  15.         else:
  16.             print("嘿,小了,小了~~~")
  17. print("遊戲結束,不玩啦^_^")
複製代碼

Kw^5.-XZqV3g~;FONj{1
1. input()函數有可能產生兩類異常:EOFError(文件末尾endoffile,當用戶按下組合鍵Ctrl+d產生)和KeyboardInterrupt(取消輸入,當用戶按下組合鍵Ctrl+c產生),再次修改上邊代碼,捕獲處理input()的兩類異常,提高用戶體驗。

<9;2(hz3L_o)N }@^?6:Qq-
2.嘗試一個新的函數int_input(),當用戶輸入整數的時候正常返回,否則提示出錯並要求重新輸入。

程序實現如圖:版權屬於:bbs.fishc.com

*, WX]e)YBkcI<H&0OLK`C6R%9!4
<tD3x6Vb0>|pXZG=?`@,FO!)d+;:e1
3.把文件關閉放在finally語句塊中執行還是會出現問題,像下邊這個代碼,當前文件夾中並不存在"My_File.txt"這個文件,那麼程序執行起來會發生什麼事情呢?你有辦法解決這個問題嗎?>;+%*Gz`~a
?'^I{Hap#zXy1S!nwj+|BZ$h~
  1. try:
  2.     f = open('My_File.txt') # 當前文件夾中並不存在"My_File.txt"這個文件T_T
  3.     print(f.read())
  4. except OSError as reason:
  5.     print('出錯啦:' + str(reason))
  6. finally:
  7. f.close()
複製代碼

4.請寫下這一節課你學習到的內容:格式不限,回憶並複述是加強記憶的好方式!

回复您的答案即可查看參考答案!N:]J'{
{rW%lP2*C&<JGk[R4K,Tb^S=$UD
D<K*me`V{o|.=c^4u Bn)
測試題答案:


本帖隱藏的內容

版權屬於:bbs.fishc.com
0.我們使用什麼方法來處理程序中出現的異常?M2_<pA-ox
v+sEWZJYU9Q:3bV|q*@(h7 Izy}5o
答:使用try……except搭配來捕獲處理程序中出現的異常。"Xj=$)R
try: 版權屬於:bbs.fishc .com
        檢測範圍來自:bbs.fishc.com
except Exception[as reason]: r&Fijw]E
        出現異常(Exception)後的處理代碼
Y%f+B
OUgns.Wrz-^Jw{uX~1<qmeR
_I,m "d[)~3|TeH?WLD*$z2tGo
1.一個try語句可以和多個except語句搭配嗎?為什麼?1!)`%T3D
4Mt3,1.eU#'A~*r`@RY}+-
答:可以。因為try語句塊中可能出現多類異常,利用多個except語句可以分別捕獲並處理我們感興趣的異常。|[VQ1a
  1. try:
  2.     sum = 1 + '1'
  3.     f = open('我是一個不存在的文檔.txt')
  4.     print(f.read())
  5.     f.close()
  6. except OSError as reason:
  7.     print('文件出錯啦T_T\n錯誤原因是:' + str(reason))
  8. except TypeError as reason:
  9.     print('類型出錯啦T_T\n錯誤原因是:' + str(reason))
複製代碼

Gj*Kg65=kvJxld9.! ?mWU
2.你知道如何統一處理多類異常嗎?56Jn2W
kndu]>|L%f@w*~$tcI#N!}"{psij
答:在except後邊使用小括號“()”把多個需要統一處理的異常括起來:YSeOE
  1. try:
  2.     int('abc')
  3.     sum = 1 + '1'
  4.     f = open('我是一個不存在的文檔.txt')
  5.     print(f.read())
  6.     f.close()
  7. except (OSError, TypeError):
  8.     print('出錯啦T_T\n錯誤原因是:' + str(reason))
複製代碼

7o=sgOTLb$.A3H48IQit
3. except後邊如果不帶任何異常類,Python會捕獲所有(try語句塊內)的異常並統一處理,但小甲魚卻不建議這麼做,你知道為什麼嗎?xi[aOK=l'
1=KF^23[;sC&x0aPlkA7zcW~`'bH
答:因為它會隱藏所有程序員未想到並且未做好準備處理的錯誤,例如用戶輸入ctrl+c試圖終止程序會被解釋為KeyboardInterrupt異常。IUADmZE4<
$`sg8q5*9tHemOA~x)6IW>{;3z'
_e7kG`0D6.lA+IK4yB=1L>
4.如果異常發生在成功打開文件後,Python跳到except語句執行,並沒有執行關閉文件的命令(用戶寫入文件的數據就可能沒有保存起來),因此我們需要確保無論如何(就算出了異常退出)文件也要被關閉,我們應該怎麼做呢?Djq>7RW=bP
qRP8i4:26USTdw.*);~OL+Ez^J
答:我們可以使用finally語句來實現,如果try語句塊中沒有出現任何運行時錯誤,會跳過except語句塊執行finally語句塊的內容。h-kc'2
PtafHjOG2->;=rqRkAY$Mg3
如果出現異常,則會先執行except語句塊的內容再接著執行finally語句塊的內容。總之,finally語句塊裡的內容就是確保無論如何都將被執行的內容!D)zoW
WubKkV16ns)=S3Qv0,9Y;*HT<:
*9IlUqXxV+,.s(iS5<QDn
5.請恢復以下代碼中馬賽克擋住的內容,使得程序執行後可以按要求輸出。
+%IE59rM_^TG<}4>;Yly'hW1o)z ?:f
答:這道題比較考腦瓜,你想到了嗎?
  1. try:
  2.     for i in range(3):
  3.         for j in range(3):
  4.             if i == 2:
  5.                 raise KeyboardInterrupt
  6.             print(i, j)
  7. except KeyboardInterrupt:
  8.     print('退出啦!')
複製代碼

jF{RLg#^Qw&B6,J}u;? 5|v

動動手答案:
=4:+SJ`Z1,fgcU T(~r2E7PjC]

本帖隱藏的內容

Powered by bbs.fishc.com
0.還記得我們第一個小遊戲嗎?只要用戶輸入非整型數據,程序立刻就會蹦出不和諧的異常信息然後崩潰。請使用剛學的異常處理方法修改以下程序,提高用戶體驗。)NRl1eXI
*RFnw<g]GTOSC[vaQX$'
答:這裡對可能導致異常的guess = int(temp)進行監測F&2()k"]
0PR3=c8!2xXw*Zl[Ir|sW<7"Bg@
代碼清單:來自:bbs.fishc.com
  1. import random

  2. secret = random.randint(1,10)
  3. print('------------------我愛魚C工作室------------------')
  4. temp = input("不妨猜一下小甲魚現在心裡想的是哪個數字:")
  5. try:   
  6.     guess = int(temp)
  7. except ValueError:
  8.     print('輸入錯誤!')
  9.     guess = secret
  10. while guess != secret:
  11.     temp = input("哎呀,猜錯了,請重新輸入吧:")
  12.     guess = int(temp)
  13.     if guess == secret:
  14.         print("我草,你是小甲魚心裡的蛔蟲嗎?!")
  15.         print("哼,猜中了也沒有獎勵!")
  16.     else:
  17.         if guess > secret:
  18.             print("哥,大了大了~~~")
  19.         else:
  20.             print("嘿,小了,小了~~~")
  21. print("遊戲結束,不玩啦^_^")
複製代碼

-5|bY?9vf^Nc&_*><SGK;
1. input()函數有可能產生兩類異常:EOFError(文件末尾endoffile,當用戶按下組合鍵Ctrl+d產生)和KeyboardInterrupt(取消輸入,當用戶按下組合鍵Ctrl+c產生),再次修改上邊代碼,捕獲處理input()的兩類異常,提高用戶體驗。];7uhw
XQ`r*w_eymC8gcEVo.R(kL9^@6NT
答:來自:bbs.fishc.com
  1. import random

  2. secret = random.randint(1,10)
  3. print('------------------我愛魚C工作室------------------')
  4. try:
  5.     temp = input("不妨猜一下小甲魚現在心裡想的是哪個數字:")   
  6.     guess = int(temp)
  7. except (ValueError, EOFError, KeyboardInterrupt):
  8.     print('輸入錯誤!')
  9.     guess = secret
  10. while guess != secret:
  11.     temp = input("哎呀,猜錯了,請重新輸入吧:")
  12.     guess = int(temp)
  13.     if guess == secret:
  14.         print("我草,你是小甲魚心裡的蛔蟲嗎?!")
  15.         print("哼,猜中了也沒有獎勵!")
  16.     else:
  17.         if guess > secret:
  18.             print("哥,大了大了~~~")
  19.         else:
  20.             print("嘿,小了,小了~~~")
  21. print("遊戲結束,不玩啦^_^")
複製代碼

(MQ+"|~gX7^elydw%[_Vj'JLArna
2.嘗試一個新的函數int_input(),當用戶輸入整數的時候正常返回,否則提示出錯並要求重新輸入。gJfR2*lT3
m?XU{sJ&^ 8Mzp]wx0C5B'!hd<
答:
  1. def int_input(prompt=''):
  2.     while True:
  3.         try:
  4.             int(input(prompt))
  5.             break
  6.         except ValueError:
  7.             print('出錯,您輸入的不是整數!')

  8. int_input('請輸入一個整數:')
複製代碼

W3L't-sg`>q[}(uYSjQ?;
3.把文件關閉放在finally語句塊中執行還是會出現問題,像下邊這個代碼,當前文件夾中並不存在"My_File.txt"這個文件,那麼程序執行起來會發生什麼事情呢?你有辦法解決這個問題嗎?F;g-!8daw
AV:pIXgw`r_B6.LiN]*ExUGS;$ta<
答:由於finally語句塊裡試圖去關閉一個並沒有成功打開的文件,因此會彈出錯誤內容如下:P
  1. >>> 出錯啦:[Errno 2] No such file or directory: 'My_File.txt'
  2. Traceback (most recent call last):
  3.   File "C:\Users\FishC000\Desktop\test.py", line 7, in <module>
  4.     f.close()
  5. NameError: name 'f' is not defined
複製代碼

我們這麼修正:
  1. try:
  2.     f = open('My_File.txt') # 當前文件夾中並不存在"My_File.txt"這個文件T_T
  3.     print(f.read())
  4. except OSError as reason:
  5.     print('出錯啦:' + str(reason))
  6. finally:
  7.     if 'f' in locals(): # 如果文件對像變量存在當前局部變量符號表的話,說明打開成功
  8.         f.close()
複製代碼
Powered by bbs.fishc.com
f$ELdrp <.^;t&m15oce[JT{N
3.請寫下這一節課你學習到的內容:格式不限,回憶並複述是加強記憶的好方式!

小甲魚希望你認真對待作業就像你希望小甲魚推出高質量視頻一樣渴望^_^



上節課我們已經掌握了能夠碰到的異常類型,name這一節我們就來學習如何檢測這些異常並處理它們。異常檢測我們可以使用try 語句來實現,任何出現在try 語句範圍內的異常都會被檢測到,我們這節課要介紹兩個模式的try 語句,
一種是try—except 語句:
語法:try :
                       檢測範圍
           except Exception [ as reason ]:
                      出現異常(Exception)後的處理代碼
try:
        f = open('我是一個不存在的文件.txt')
        print(f.read())
        f.close
except OSError:
        print('文件出錯啦')
============ RESTART: C:/Users/XiangyangDai/Desktop/上課代碼/33-1.py ============
文件出錯啦
這樣處理對於用戶來說很好,但是對於程序員來說,我們還想要知道報錯的具體錯誤類型,這時,我們就使用可選參數as reason(其中reason 是一個變量,得到錯誤具體,需要str(reason) 才能打印)
try:
        f = open('我是一個不存在的文件.txt')
        print(f.read())
        f.close
except OSError as reason:
        print('文件出錯啦!\n錯誤的原因是:' + str(reason))
============ RESTART: C:/Users/XiangyangDai/Desktop/上課代碼/33-1.py ============
文件出錯啦!
錯誤的原因是:[Errno 2] No such file or directory: '我是一個不存在的文件.txt'
另外,一個try 可以與多個except 搭配,以監測多種類型的錯誤。但是在這種情況下,程序會在第一個出錯的位置檢查有沒有對應的except,如果有,就僅打印第一次出錯的出錯信息,如果沒有第一個出錯對應的except,則還是紅色原始報錯。
try:
        sum = 1 + '1'
        f = open('我是一個不存在的文件.txt')
        print(f.read())
        f.close
except OSError as reason:
        print('文件出錯啦!\n錯誤的原因是:' + str(reason))
except TypeError as reason:
         print('類型出錯啦!\n錯誤的原因是:' + str(reason))
============ RESTART: C:/Users/XiangyangDai/Desktop/上課代碼/33-1.py ============
類型出錯啦!
錯誤的原因是:unsupported operand type(s) for +: 'int' and 'str'
try:
        int('abc') #ValueError
        sum = 1 + '1' #類型錯誤TypeError
        f = open('我是一個不存在的文件.txt') #OSError
        print(f.read())
        f.close
except OSError as reason:
        print('文件出錯啦!\n錯誤的原因是:' + str(reason))
except TypeError as reason:
         print('類型出錯啦!\n錯誤的原因是:' + str(reason ))
============ RESTART: C:/Users/XiangyangDai/Desktop/上課代碼/33-1.py ============
Traceback (most recent call last):
  File "C:/Users/XiangyangDai/Desktop/上課代碼/33-1.py", line 2, in <module>
    int('abc') #ValueError
ValueError: invalid literal for int() with base 10 : 'abc'
如果你想檢測任何類型的錯誤,只要程序出錯,就提示出錯信息,不管是什麼類型的錯誤:
try:
        int('abc') #ValueError
        sum = 1 + '1' #類型錯誤TypeError
        f = open('我是一個不存在的文件.txt') #OSError
        print(f.read())
        f.close
except :
        print('出錯啦!')
============ RESTART: C:/Users/XiangyangDai/Desktop/上課代碼/33-1.py ============
出錯啦!
但是這種做法是不推薦的,因為這會隱藏程序員未想到的所有未準備好處理的異常和錯誤。例如當按住ctrl + C 想停止程序時,也會檢測為KeyboardError,而彈出提示信息。
要注意的是,try 語句的檢測範圍內一旦出現異常,剩下的語句將不會被執行。
第二種是try — finally 語句:
語法:try:
                    檢測範圍
          except Exception [as reason]:
                   出現異常(Exception)後的處理代碼
          finally:
                  無論如何都會被執行的代碼
在上面的例子中,如果異常出現在打開文件之後,然後文件沒有被關閉,這是非常不妥的。可以使用try — finally 語句改進。
try:
        f = open('C:\\Users\\XiangyangDai\\Desktop\\一個文件.txt', 'w')
        print(f.write('我存在了!')) #這裡會寫入'我存在了!'打印的是寫入的字符數
        sum = 1 + '1'
except (OSError, TypeError):
        print('出錯啦!')
finally:
        f.close()
============ RESTART: C:/Users/XiangyangDai/Desktop/上課代碼/33-2.py ============
5
出錯啦!
總結一下:如果try 語句塊裡面沒有任何運行的錯誤的時候,就會跳過exception語句塊,然後執行finally 語句塊裡的內容,如果出現了異常,會根據異常的內容去找到對應的異常執行代碼,然後還會執行finally。也就是說,無論如何,finally語句塊裡的內容都是確保將被執行的內容。即使出現的異常在exception 中沒有定義對應的處理代碼,finally 也會被執行。
最後說一下raise 語句:
可以使用raise 語句引發一個異常

>>> raise
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    raise
RuntimeError: No active exception to reraise
>>> raise ZeroDivisionError('除數為零的異常')
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    raise ZeroDivisionError('除數為零的異常')
ZeroDivisionError:除數為零的異常

0 留言:

發佈留言