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