Python?錯誤處理的最佳實踐
1. 什么是異常?
異常(Exception)就是程序運行時發(fā)生的錯誤,比如試圖打開一個不存在的文件、除以零或者輸入了非法數(shù)據(jù)。Python 會拋出異常來告訴你“嘿,這里出問題了!”。如果不處理,程序會直接崩潰,打印一堆錯誤信息(就是 traceback)。
異常處理的核心是用代碼“捕獲”這些錯誤,防止程序崩掉,還能給用戶友好的提示。
2. 常見的 Python 異常類型
Python 內置了很多異常類型,了解它們能幫你更好地處理問題。以下是一些常見的異常:
ZeroDivisionError:除以零時觸發(fā)。FileNotFoundError:試圖打開不存在的文件。ValueError:函數(shù)接收到不合適的參數(shù),比如把字符串傳給int()。TypeError:類型錯誤,比如試圖把字符串和整數(shù)相加。IndexError:列表索引超出范圍。KeyError:訪問字典中不存在的鍵。
這些異常都是 Python 的內置類,繼承自 Exception 類。你可以在代碼中捕獲它們。
3. 基本的 try-except 結構
Python 用 try-except 塊來處理異常?;舅悸肥牵喊芽赡艹鲥e的代碼放進 try 塊,如果出錯了,就跳到 except 塊執(zhí)行。
來看個簡單的例子:
try:
num = int(input("請輸入一個數(shù)字: "))
result = 10 / num
print(f"10 除以 {num} 等于 {result}")
except:
print("出錯了!可能輸入了非法數(shù)字或除以零。")運行這段代碼:
- 如果用戶輸入一個合法數(shù)字,比如
5,程序會打印10 除以 5 等于 2.0。 - 如果輸入了非數(shù)字(比如
"abc")或0,程序會跳到except塊,打印錯誤提示,而不會崩潰。
這個 except 是個“通吃”模式,捕獲所有異常。但最好別這樣用,因為你不知道具體出了啥問題。接下來我們改進它。
4. 捕獲特定異常
與其捕獲所有異常,不如只捕獲你關心的特定異常類型。這樣能更精準地處理問題。Python 允許在 except 后指定異常類型。
改寫上面的例子:
try:
num = int(input("請輸入一個數(shù)字: "))
result = 10 / num
print(f"10 除以 {num} 等于 {result}")
except ValueError:
print("請輸入一個合法的數(shù)字!")
except ZeroDivisionError:
print("不能除以零!")現(xiàn)在:
- 如果輸入
"abc",會觸發(fā)ValueError,打印“請輸入一個合法的數(shù)字!”。 - 如果輸入
0,會觸發(fā)ZeroDivisionError,打印“不能除以零!”。 - 其他異常(比如
KeyboardInterrupt)不會被捕獲,程序會照常報錯。
你可以捕獲多個異常,也可以把異常對象保存下來,查看具體錯誤信息:
try:
num = int(input("請輸入一個數(shù)字: "))
result = 10 / num
except ValueError as e:
print(f"輸入錯誤: {e}")
except ZeroDivisionError as e:
print(f"除零錯誤: {e}")這里 as e 把異常對象存到變量 e,可以打印更詳細的錯誤信息。
5. 使用 else 和 finally
try-except 還有兩個好用的伙伴:else 和 finally。
else:如果try塊沒出錯,就執(zhí)行else塊。適合放那些依賴try塊成功的代碼。finally:不管try塊有沒有出錯,finally塊都會執(zhí)行。常用來做清理工作,比如關閉文件。
來看個例子:
try:
num = int(input("請輸入一個數(shù)字: "))
result = 10 / num
except ValueError:
print("請輸入合法數(shù)字!")
except ZeroDivisionError:
print("不能除以零!")
else:
print(f"計算成功!結果是: {result}")
finally:
print("程序結束,清理完成!")運行效果:
- 輸入
5:打印“計算成功!結果是: 2.0”和“程序結束,清理完成!”。 - 輸入
"abc":打印“請輸入合法數(shù)字!”和“程序結束,清理完成!”。 - 輸入
0:打印“不能除以零!”和“程序結束,清理完成!”。
finally 特別適合確保資源被正確釋放,比如:
try:
file = open("data.txt", "r")
content = file.read()
except FileNotFoundError:
print("文件沒找到!")
else:
print(f"文件內容: {content}")
finally:
try:
file.close()
print("文件已關閉")
except NameError:
print("文件從未打開,無需關閉")這里 finally 確保文件被關閉,即使文件沒找到(導致 file 未定義)也能安全處理。
6. 拋出異常
有時候你想主動拋出異常,比如檢查到用戶輸入不符合要求??梢杂?nbsp;raise 關鍵字拋出異常。
例子:
def divide(a, b):
if b == 0:
raise ZeroDivisionError("除數(shù)不能為零!")
return a / b
try:
result = divide(10, 0)
except ZeroDivisionError as e:
print(f"錯誤: {e}")運行會打印“錯誤: 除數(shù)不能為零!”。你可以用 raise 拋出任何內置異常,或者直接用 raise Exception("自定義消息")。
還可以“重新拋出”異常:
try:
num = int(input("請輸入一個數(shù)字: "))
except ValueError as e:
print(f"輸入錯誤: {e}")
raise # 重新拋出原異常這樣會在處理完錯誤后,繼續(xù)把異常拋給上層調用者。
7. 自定義異常
當內置異常不夠用時,你可以定義自己的異常類。自定義異常通常繼承自 Exception 類。
例子:
class CustomValueError(Exception):
"""自定義異常,用于值不符合要求"""
pass
def check_age(age):
if age < 0 or age > 150:
raise CustomValueError("年齡必須在0到150之間!")
return age
try:
age = check_age(200)
except CustomValueError as e:
print(f"錯誤: {e}")運行會打印“錯誤: 年齡必須在0到150之間!”。自定義異常讓代碼更清晰,尤其在復雜項目中。
8. 錯誤處理的最佳實踐
最后,分享一些寫錯誤處理代碼的建議:
- 捕獲特定異常:別用“通吃”的
except,盡量指定具體的異常類型。 - 提供清晰的錯誤信息:用戶看到錯誤時,應該知道問題出在哪,怎么解決。
- 用 else 和 finally 合理組織代碼:
else放依賴try成功的邏輯,finally放清理工作。 - 別濫用異常:異常是用來處理“異常情況”的,別用它來控制正常流程(比如代替
if判斷)。 - 記錄錯誤日志:在實際項目中,用
logging模塊記錄異常,方便調試。
例子(帶日志):
import logging
logging.basicConfig(level=logging.ERROR, filename="app.log")
try:
num = int(input("請輸入一個數(shù)字: "))
result = 10 / num
except ValueError as e:
logging.error(f"輸入錯誤: {e}")
print("請輸入合法數(shù)字!")
except ZeroDivisionError as e:
logging.error(f"除零錯誤: {e}")
print("不能除以零!")
else:
print(f"結果: {result}")
finally:
print("程序結束!")這個例子會把錯誤記錄到 app.log 文件,方便排查問題。
到此這篇關于Python 錯誤處理詳解的文章就介紹到這了,更多相關Python 錯誤處理詳解內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
執(zhí)行Django數(shù)據(jù)遷移時報 1091錯誤及解決方法
這篇文章主要介紹了執(zhí)行Django數(shù)據(jù)遷移,報錯 1091,需要的朋友可以參考下2019-10-10
Selenium獲取登錄Cookies并添加Cookies自動登錄的方法
這篇文章主要介紹了Selenium獲取登錄Cookies并添加Cookies自動登錄的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-12-12
Python簡單獲取網(wǎng)卡名稱及其IP地址的方法【基于psutil模塊】
這篇文章主要介紹了Python簡單獲取網(wǎng)卡名稱及其IP地址的方法,結合實例形式分析了Python基于psutil模塊針對本機網(wǎng)卡硬件信息的讀取操作簡單使用技巧,需要的朋友可以參考下2018-05-05
修改Python的pyxmpp2中的主循環(huán)使其提高性能
這篇文章主要介紹了修改Python的pyxmpp2中的主循環(huán)使其提高性能,pyxmpp2是Python中使用需XMPP協(xié)議的一個常用工具,要的朋友可以參考下2015-04-04
Python 編碼規(guī)范(Google Python Style Guide)
本項目并非 Google 官方項目, 而是由國內程序員憑熱情創(chuàng)建和維護,對于想學習python的朋友可以參考一下2018-05-05
Python使用pytorch動手實現(xiàn)LSTM模塊
這篇文章主要介紹了Python使用pytorch動手實現(xiàn)LSTM模塊,LSTM是RNN中一個較為流行的網(wǎng)絡模塊。主要包括輸入,輸入門,輸出門,遺忘門,激活函數(shù),全連接層(Cell)和輸出2022-07-07

