靜態(tài)網(wǎng)站怎么做留言板南京谷歌seo
異常
在編程中,異常是指程序運行過程中發(fā)生的意外事件,這些事件通常中斷了正常的指令流程。它們可能是由于錯誤的輸入數(shù)據(jù)、資源不足、非法操作或其他未預(yù)料到的情況引起的。Python中,當(dāng)遇到這類情況時,會拋出一個異常對象,如果這個異常沒有被捕獲處理,程序?qū)K止執(zhí)行。
異常處理
異常處理是一種編程技術(shù),用于捕捉程序運行過程中發(fā)生的異常,并采取適當(dāng)措施來響應(yīng)這些異常,而不是讓程序直接崩潰。這包括捕獲異常、分析異常類型以及根據(jù)異常類型決定如何恢復(fù)或優(yōu)雅地結(jié)束程序。
Python提供了try、except、else和finally語句來實現(xiàn)異常處理機(jī)制:
- try: 嘗試執(zhí)行的代碼塊,可能拋出異常的地方。
- except: 捕獲并處理特定類型的異常。可以有多個except子句來捕獲不同類型的異常。
- else: 如果沒有異常發(fā)生,則執(zhí)行這里的代碼塊。
- finally: 不管是否發(fā)生異常,都會執(zhí)行的代碼塊,通常用來清理資源。
處理示例
針對常見的一些異常做處理示例。
處理處 ZeroDivisionError 異常
在學(xué)習(xí)四則運算的時候,我們都知道除法運行中除數(shù)不能為0。
Python中同樣也有四則運算,我們練習(xí)的時候自然會避免出現(xiàn)除數(shù)為0的情況。在實際編程過程中,我們很少會除以一個固定數(shù)值,大多數(shù)時候都是除以一個變量,而這個變量的值,往往是在程序運行中根據(jù)各種情況計算出來的,這個時候,我們就沒辦法保證除數(shù)不能為0了。那么真的遇到除數(shù)為0的情況,Python會如何應(yīng)對呢?
程序執(zhí)行出現(xiàn)錯誤,提示 ZeroDivisionError :division by zero。這個是很明顯的提示,并且明確指出在模塊第1行。
為了防止程序錯誤中止,我們可以通過異常處理是程序繼續(xù)執(zhí)行。
try:result = 10 / 0 # 這里會嘗試執(zhí)行除法運算
except ZeroDivisionError:# 捕獲到ZeroDivisionError后,輸出提示信息print("錯誤:不能除以零")
print("程序繼續(xù)執(zhí)行")
程序打印了錯誤的提示,然后正確的向下執(zhí)行。
這就是異常處理的基礎(chǔ)語法和使用,但是有時候程序出現(xiàn)異常不出現(xiàn)異常是兩種處理方法,這個時候我們就需要用到else語句了。
div = 2
div *= 2
div += 3
div //= 3
div -= 1
try:result = 10 / div # 這里會嘗試執(zhí)行除法運算
except ZeroDivisionError:# 捕獲到ZeroDivisionError后,輸出提示信息print("錯誤:不能除以零")
else:print("結(jié)果是:", result)
print("程序繼續(xù)執(zhí)行")
根據(jù)結(jié)果,我們發(fā)現(xiàn)程序走了else的分支,那么很明顯,異常沒有發(fā)生,輸出結(jié)果也符合預(yù)期。
最后講一下比較特殊的finally。這個語句下的分支,是不管異常發(fā)生不發(fā)生,都能夠執(zhí)行的語句。通常會用來關(guān)閉某些資源,比如上篇說的文件的資源,就會在finally代碼塊中調(diào)用close()方法關(guān)閉文件資源。
finally語句使用新的異常進(jìn)行示例。
FileNotFoundError
在進(jìn)行文件處理的時候,可能不小心填錯了地址或者寫錯了文件格式。這個時候調(diào)用文件流的open方法就會出現(xiàn)異常。
file = open("example.txt")
content = file.read()
print(content)
一個很明顯的文件不存在的提示。我們同樣使用try…except進(jìn)行異常處理
try:file = open("example.txt")content = file.read()
except FileNotFoundError:print("文件未找到")
else:print(content)
根據(jù)我們學(xué)習(xí)的文件流知識嗎,我們在文件操作過程中,使用了open函數(shù)就一定要調(diào)用close函數(shù)關(guān)閉資源。那么流關(guān)閉的調(diào)用應(yīng)該放在哪里呢?仔細(xì)想想,放在正常流程中,程序出現(xiàn)錯誤怎么辦?放在異常處理中,那正常邏輯不是得也寫一份?那么finally無疑是最好的選擇了。
寫在finally中有兩個好處:
確保資源總是被釋放:無論try塊中的代碼是否拋出異常,finally塊都會執(zhí)行。這意味著即使程序因為某些未預(yù)料到的錯誤提前退出,finally中的清理代碼也會運行,從而確保打開的資源被正確關(guān)閉,防止資源泄露。
邏輯清晰:將資源清理工作放在finally塊中,可以使得異常處理邏輯(except塊)專注于處理異常本身,而資源管理則由finally統(tǒng)一負(fù)責(zé),這樣代碼結(jié)構(gòu)更加清晰,便于理解和維護(hù)。
file = open("example.txt")
try:content = file.read()print(content)
except FileNotFoundError:print("文件未找到")
finally:file.close() # 確保文件被關(guān)閉
這樣的話,資源最終都會關(guān)閉。
多個異常
實際編寫代碼時,代碼通常會幾行幾十行,那么出現(xiàn)異常的種類也可能不止一種,那么怎么去處理多種異常呢?
try:num = int(input("請輸入一個數(shù)字: "))result = 10 / num
except ValueError:print("輸入的不是有效的數(shù)字")
except ZeroDivisionError:print("不能除以零")
像這樣,按順序使用except語句處理即可。
那么問題又來了,兩個三個,甚至四個五個我都一行行去寫沒問題,十幾個怎么辦?異常處理比代碼還長,誰看誰頭痛。
python有處理所有異常的辦法。
try:# 可能拋出任何類型的異常的代碼...
except Exception as e:print(f"發(fā)生了異常: {e}")
使用Exception,這表示所有的異常都會被捕獲住。
問題又又來了,我就想單獨處理FileNotFoundError,其他異常再統(tǒng)一處理,行不行?
當(dāng)然可以! 請看。
try:# 可能拋出多種類型的異常的代碼file = open("nonexistent_file.txt") # 示例:嘗試打開一個不存在的文件content = file.read()print(content)
except FileNotFoundError:print("錯誤:指定的文件未找到。")
except Exception as e:print(f"發(fā)生了其他異常: {e}") # 捕獲除FileNotFoundError之外的所有異常
finally:# 關(guān)閉文件等清理操作,如果文件已成功打開的話if 'file' in locals() and not file.closed:file.close()
在python中,except語句存在多個同時使用時,按從上到下的順序執(zhí)行。按上面代碼來解釋就是:python發(fā)現(xiàn)你程序執(zhí)行的時候出現(xiàn)異常,先檢查是不是FileNotFoundError,是就在這個except中進(jìn)行處理,不是的話再往下執(zhí)行匹配下一個異常類。這樣的話別說處理一個,處理十個都沒問題。
結(jié)尾
python的異常處理就這些內(nèi)容了,大家在實際使用的時候要靈活運用,根據(jù)不同的業(yè)務(wù)和場景靈活使用try…except…else…finally,來得到自己想要的結(jié)果。
作業(yè)
-
查詢常見的一些異常。
-
自己編寫代碼處理這些異常,從單個,到多個,再到單個+所有的模式。