在
Python 中,還有另一種異常處理結(jié)構(gòu),就是 try except else 語句,也就是在原來 try except 語句的基礎(chǔ)上再添加一個 else 子句,其作用是指定當(dāng) try 塊中沒有發(fā)現(xiàn)異常時要執(zhí)行的代碼。換句話說,當(dāng) try 塊中發(fā)現(xiàn)異常,則 else 塊中的語句將不會被執(zhí)行。
例如如下程序:
- s = input('請輸入除數(shù):')
- try:
- result = 20 / int(s)
- print('20除以%s的結(jié)果是: %g' % (s , result))
- except ValueError:
- print('值錯誤,您必須輸入數(shù)值')
- except ArithmeticError:
- print('算術(shù)錯誤,您不能輸入0')
- else:
- print('沒有出現(xiàn)異常')
- print("程序繼續(xù)運行")
上面程序為異常處理流程添加了 else 塊,當(dāng)程序中的 try 塊沒有出現(xiàn)異常時,程序就會執(zhí)行 else 塊。運行上面程序,如果用戶輸入導(dǎo)致程序中的 try 塊出現(xiàn)了異常,則運行結(jié)果如下:
請輸入除數(shù):a
值錯誤,您必須輸入數(shù)值
程序繼續(xù)運行
如果用戶輸入讓程序中的 try 塊順利完成,則運行結(jié)果如下:
請輸入除數(shù):3
20 除以3 的結(jié)果是:6.66667
沒有出現(xiàn)異常
程序繼續(xù)運行
看到這里,可能有讀者覺得奇怪,既然只有當(dāng) try 塊沒有異常時才會執(zhí)行 else 塊,那么直接把 else 塊的代碼放在 try 塊的代碼的后面不就行了?
實際上大部分語言的異常處理都沒有 else 塊,它們確實是將 else 塊的代碼直接放在 try 塊的代碼的后面的,因為對于大部分場景而言,直接將 else 塊的代碼放在 try 塊的代碼的后面即可。
但 Python 的異常處理使用 else 塊絕不是多余的語法,當(dāng) try 塊沒有異常,而 else 塊有異常時,就能體現(xiàn)出 else 塊的作用了。例如如下程序:
- def else_test():
- s = input('請輸入除數(shù):')
- result = 20 / int(s)
- print('20除以%s的結(jié)果是: %g' % (s , result))
- def right_main():
- try:
- print('try塊的代碼,沒有異常')
- except:
- print('程序出現(xiàn)異常')
- else:
- # 將else_test放在else塊中
- else_test()
- def wrong_main():
- try:
- print('try塊的代碼,沒有異常')
- # 將else_test放在try塊代碼的后面
- else_test()
- except:
- print('程序出現(xiàn)異常')
- wrong_main()
- right_main()
上面程序中定義了一個 else_test() 函數(shù),該函數(shù)在運行時需要接收用戶輸入的參數(shù),隨著用戶輸入數(shù)據(jù)的不同可能導(dǎo)致異常。接下來程序定義了 right_main() 和 wrong_main() 兩個函數(shù),其中 right_main() 將 else_test() 函數(shù)放在 else 塊內(nèi);而 wrong_main() 將 else_test() 函數(shù)放在 try 塊的代碼的后面。
正如上面所介紹的,當(dāng) try 塊和 else 塊都沒有異常時,將 else_test() 函數(shù)放在 try 塊的代碼的后面和放在 else 塊中沒有任何區(qū)別。例如,如果用戶輸入的數(shù)據(jù)沒有導(dǎo)致程序出現(xiàn)異常,則將看到程序產(chǎn)生如下輸出結(jié)果:
try塊的代碼,沒有異常
請輸入除數(shù):4
20除以4的結(jié)果是: 5
try塊的代碼,沒有異常
請輸入除數(shù):4
20除以4的結(jié)果是: 5
但如果用戶輸入的數(shù)據(jù)讓 else_test() 函數(shù)出現(xiàn)異常(try 塊依然沒有任何異常),此時程序就會產(chǎn)生如下輸出結(jié)果:
try塊的代碼,沒有異常
請輸入除數(shù):0
程序出現(xiàn)異常
try塊的代碼,沒有異常
請輸入除數(shù):0
Traceback (most recent call last):
File "C:\Users\mengma\Desktop\1.py", line 21, in <module>
right_main()
File "C:\Users\mengma\Desktop\1.py", line 12, in right_main
else_test()
File "C:\Users\mengma\Desktop\1.py", line 3, in else_test
result = 20 / int(s)
ZeroDivisionError: division by zero
對比上面兩個輸出結(jié)果,用戶輸入的都是 0,這樣都會導(dǎo)致 else_test() 函數(shù)出現(xiàn)異常。如果將 else_test() 函數(shù)放在 try 塊的代碼的后面,此時 else_test() 函數(shù)運行產(chǎn)生的異常將會被 try 塊對應(yīng)的 except 捕獲,這正是 Python 異常處理機制的執(zhí)行流程:但如果將 else_test() 函數(shù)放在 else 塊中,當(dāng) else_test() 函數(shù)出現(xiàn)異常時,程序沒有 except 塊來處理該異常,該異常將會傳播給 Python 解釋器,導(dǎo)致程序中止。
對比上面兩個輸出結(jié)果,不難發(fā)現(xiàn),放在 else 塊中的代碼所引發(fā)的異常不會被 except 塊捕獲。
所以,如果希望某段代碼的異常能被后面的 except 塊捕獲,那么就應(yīng)該將這段代碼放在 try 塊的代碼之后;如果希望某段代碼的異常能向外傳播(不被 except 塊捕獲),那么就應(yīng)該將這段代碼放在 else 塊中。