Python中的代碼異常處理你掌握了嗎
Python 使用稱為異常(exception)的特殊對象來管理程序執(zhí)行期間發(fā)生的錯誤。每當發(fā)生讓Python不知所措的錯誤時,它都會創(chuàng)建一個異常對象。如果你編寫了處理該異常的代碼,程序?qū)⒗^續(xù)運行;如果你未對異常進行處理,程序?qū)⑼V?,并顯示一個 traceback,其中包含有關異常的報告。
異常是使用 try-except 代碼塊處理的。try-except 代碼塊讓 Python 執(zhí)行指定的操作,同時告訴 Pysthon 在發(fā)生異常時應該怎么辦。在使用 try-except 代碼塊時,即便出現(xiàn)異常,程序也將繼續(xù)運行:顯示你編寫的友好的錯誤消息,而不是令用戶迷惑的 traceback。
處理 ZeroDivisionError 異常
下面來看一種導致 Pyton 引發(fā)異常的簡單錯誤。你可能知道不能將數(shù)除以人 0,但還是讓Python試試看吧:
print(5/0)
Python 無法這樣做,因此你將看到一個 traceback:
Traceback (most recent call last):
File "division calculator.py", line 1, in <module>
print(5/0)
~^~
①ZeroDivisionError: division by zero
在上述traceback 中,錯誤 ZeroDivisionError 是個異常對象(見①)。Python 在無法按你的要求做時,就會創(chuàng)建這種對象。在這種情況下,Python 將停止運行程序,并指出引發(fā)了哪種異常,而我們可根據(jù)這些信息對程序進行修改。下面將告訴Python,在發(fā)生這種錯誤時該怎么辦。這樣,如果再次發(fā)生這樣的錯誤,我們就有所準備了。
使用 try-except 代碼塊
當你認為可能發(fā)生錯誤時,可編寫一個 try-except 代碼塊來處理可能引發(fā)的異常。你讓 Python 嘗試運行特定的代碼,并告訴它如果這些代碼引發(fā)了指定的異常,該怎么辦。
處理 zeroDivisionError 異常的 try-except 代碼塊類似于下面這樣:
try: ??print(5/0) except?ZeroDivisionError: ??print("You?can't?divide?by?zero!")
這里將導致錯誤的代碼行 print(5/0)放在一個try 代碼塊中。如果 try代碼塊中的代碼運行起來沒有問題,Python 將跳過 except 代碼塊;如果 try 代碼塊中的代碼導致錯誤,Python將查找與之匹配的 except 代碼塊并運行其中的代碼。
在這個示例中,try 代碼塊中的代碼引發(fā)了 ZeroDivisionError 異常,因此 Python 查找指出了該怎么辦的 except 代碼塊,并運行其中的代碼。這樣,用戶看到的是一條友好的錯誤消息,而不是 traceback:
You can'+ divide by zero!
如果 try-except 代碼塊后面還有其他代碼,程序?qū)⒗^線運行,因為Python已經(jīng)知道了如何處理錯誤。下面來看一個在捕獲錯誤后讓程序繼續(xù)運行的示例。
使用異常避免崩潰
如果在錯誤發(fā)生時,程序還有工作沒有完成,妥善地處理錯誤就顯得尤其重要。這種情況經(jīng)當出現(xiàn)在要求用戶提供輸人的程序中。如果程序能夠妥善地處理無效輸人,就能提不用戶提供有效輸人,而不至于崩潰。
下面來創(chuàng)建一個只執(zhí)行除法運算的簡單計算器:
print("Give?me?two?numbers,?and?I'll?divide?them.") print("Enter?'g'?to?quit.") while?True: ①????first?number?=?input?("First_number:?") ??????if?first?number?==?'q': ?????????break ②????second_number?=?input("Second_number:?") ??????if?second?number?==?'q': ?????????break ③????answer?=?int(first_number)?/?int(second_number) ??????print(answer)
在①處,程序提示用戶輸人一個數(shù),并將其賦給變量 first_number。如果用戶輸人的不是表示退出的9,就再提示用戶輸人一個數(shù),并將其賦給變量 second_ number(見②)。接下來,計算這兩個數(shù)的商(見③)。這個程序沒有采取任何處理錯誤的措施,因此在執(zhí)行除數(shù)為 0 的除法運算時,它將崩潰:
Give me two numbers, and I'll divide them.
Enter 'q' to quit.
First number: 5
Second number: 0
Traceback (most recent call last):
File "division_calculator.py", line 11, in <module>
answer = int (first number) / int(second number)
~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
ZeroDivisionError: division by zero
程序崩潰可不好,讓用戶看到 traceback 也不是個好主意。不懂技術的用戶會感到糊涂,懷有惡意的用戶還能通過 traceback 獲悉你不想讓他們知道的信息。例如,他們將知道你的程序文件的名稱,還將看到部分不能正確運行的代碼。有時候,訓練有素的攻擊者可根據(jù)這些信息判斷出可對你的代碼發(fā)起什么樣的攻擊。
else 代碼塊
通過將可能引發(fā)錯誤的代碼放在 try-except 代碼塊中,可提高程序抵御錯誤的能力。因為錯誤是執(zhí)行除法運算的代碼行導致的,所以需要將它放到 try-except 代碼塊中。這個示例還包含一個else 代碼塊,只有try代碼塊成功執(zhí)行才需要繼續(xù)執(zhí)行的代碼,都應放到else代碼塊中:
--snip-- while?True: ??--Ship-- ??if?second?number?==?'g': ????break ①??try: ????answer?=?in(first?_number)?/?int?(second?_number) ②??except?ZeroDivisionError: ????print("You?can't?divide?by?0!") ③??else: ????print(answer)
我們讓Python 嘗試執(zhí)行 try代碼塊中的除法運算(見①),這個代碼塊只包含可能導致錯誤的代碼。依賴 try 代碼塊成功執(zhí)行的代碼都被放在else 代碼塊中。在這個示例中,如果除法運算成功,就使用else 代碼塊來打印結(jié)果(見③)。
except 代碼塊告訴 Python,在出現(xiàn) zeroDivisionError 異常時該怎么辦(見②)。如果try代碼塊因零除錯誤而失敗,就打印一條友好的消息,告訴用戶如何避免這種錯誤。程序會繼續(xù)運行,而用戶根本看不到 traceback:
Give me two numbers, and I'll divide them.
Enter 'q' to quit.
First number: 5
Second number: O
You can't divide by 0!
First number: 5
Second number: 2
2.5
First number: q
只有可能引發(fā)異常的代碼才需要放在try 語向中。有時候,有一些僅在try 代碼塊成功執(zhí)行時才需要運行的代碼,這些代碼應放在else 代碼塊中。except 代碼塊告訴 Python,如果在嘗試運行 try代碼塊中的代碼時引發(fā)了指定的異常該怎么辦。
通過預測可能發(fā)生錯誤的代碼,可編與穩(wěn)健的程序。它們即便面臨無效數(shù)據(jù)或缺少資源,也能繼續(xù)運行,不受無意的用戶錯誤和惡意攻擊的影響。
靜默失敗
在上一個示例中,我們告訴用戶有一個文件找不到。但并非每次捕獲異常都需要告訴用戶,從有時候希望程序在發(fā)生異常時保持靜默,就像什么都沒有發(fā)生一樣繼續(xù)運行。要讓程序靜默失敗,可像通常那樣編寫 try 代碼塊,但在except 代碼塊中明確地告訴Python什么都不要做。
Python有一個pass 語句,可在代碼塊中使用它來讓Python什么都不做:
def?count?words?(path)?: ????"""計算一個文件大致包含多少個單詞""" ????try: ??????~~ship~~ ????except?FileNotFoundError: ??????pass? ????else: ??????~~snip~~
相比于上一個程序,這個程序唯一的不同之處是,except 代碼塊包含一條pass語句?,F(xiàn)在,當出現(xiàn) FileNotFoundError 異常時,雖然仍將執(zhí)行 except 代碼塊中的代碼,但什么都不會發(fā)生。當這種錯誤發(fā)生時,既不會出現(xiàn) traceback,也沒有任何輸出。用戶將看到存在的每個文件包含多少個單詞,但沒有任何跡象表明有一個文件未找到:
The file alice.txt has about 29594 words .
The file moby dick. txt has about 215864 words .
The file little women.txt has about 189142 words.
pass 語向還充當了 占位符,提醒你在程序的某個地方什么都沒有做,而且以后地許要在這型水世什么。例如,在這個程序中,我們可能決定特找不到的文件的臺稱寫人文什missing_fles.txt。雖然用戶看不到這個文件,但我們可以讀取它。進而處理所有找不到文件的回題。
決定報告哪些錯誤
該在什么情況下向用戶報告錯誤?又該在什么情況下靜默失敗呢?如果用戶知道要分析哪些文件,他們可能希望在有文件未被分析時出現(xiàn)一條消息來告知原因。如果用廣只想看到結(jié)果,并不知道要分析哪些文件,可能就無須在有些文件不存在時告知他們。向用戶顯示他們不想看到的信息可能會降低程序的可用性。Python 的錯誤處理結(jié)構(gòu)讓你能夠細致地控制與用戶共享錯誤信息的程度,要共享多少信息由你決定。
編寫得很好且經(jīng)過恰當測試的代碼不容易出現(xiàn)內(nèi)部錯誤,如語法錯誤和邏輯錯誤,但只要程序依賴于外部因素,如用戶輸人、是否存在指定的文件、是否有網(wǎng)絡連接,就有可能出現(xiàn)異器。憑借經(jīng)驗可判斷該在程序的什么地方包含昇常處理塊,以及出現(xiàn)錯誤時該向用戶提供多少相關的信息。
到此這篇關于Python中的代碼異常處理你掌握了嗎的文章就介紹到這了,更多相關Python異常處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
全網(wǎng)最詳細的PyCharm+Anaconda的安裝過程圖解
這篇文章主要介紹了全網(wǎng)最詳細的PyCharm+Anaconda的安裝過程圖解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01Jupyter Notebook切換虛擬環(huán)境的三種方法
本文主要介紹了Jupyter Notebook切換虛擬環(huán)境的三種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-07-07python3 實現(xiàn)除法結(jié)果為整數(shù)
這篇文章主要介紹了python3 實現(xiàn)除法結(jié)果為整數(shù),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03