從零開始:Python語言進階之異常處理

一、認識異常:程序運行中的“意外事件”

?

在編寫Python程序時,即使代碼語法完全正確,運行過程中也可能遭遇各種意外情況。這些意外被稱為異常,它們會打斷程序的正常執行流程。例如,當我們嘗試打開一個不存在的文件、用0作為除數進行除法運算,或者對不兼容的數據類型執行操作時,Python解釋器就會拋出異常。

?

1.1 常見內置異常類型

?

Python提供了豐富的內置異常類,理解這些基礎類型是掌握異常處理的第一步:

?

①? ZeroDivisionError?:當嘗試除以0時觸發。例如:

result = 5 / 0  # 立即引發ZeroDivisionError

②? FileNotFoundError?:使用?open()?函數打開不存在的文件時出現。例如:

f = open('nonexistent.txt', 'r')  # 找不到文件會引發此異常

③? TypeError?:操作或函數作用于不匹配的數據類型。例如:

text = "hello"
length = len(text) + 10  # 正確,但 len(text) + "10" 會引發TypeError

④? ValueError?:數據的值不符合預期格式。例如:

num = int("abc")  # 無法轉換為整數,引發ValueError

1.2 異常的本質:特殊對象

?

每個異常都是一個對象,繼承自內置的?BaseException?類。當異常發生時,Python會創建一個對應類型的異常對象,并沿著調用棧向上傳遞,直到被捕獲或導致程序終止。例如,?ZeroDivisionError?異常對象包含了錯誤類型和發生錯誤的上下文信息。

?

二、基礎異常處理:try - except語句

?

2.1 基礎語法結構

?

?try - except?是Python處理異常的核心語句,其結構如下:

try:# 可能引發異常的代碼塊pass
except ExceptionType:# 捕獲到指定類型異常時執行的代碼pass

①? try?塊:放置可能產生異常的代碼,例如文件操作、數據轉換等。

?

②? except?塊:用于捕獲并處理特定類型的異常。如果?try?塊中的代碼引發異常,程序會立即跳轉到對應的?except?塊執行。

?

2.2 簡單示例

?

以文件讀取為例:

try:file = open('test.txt', 'r')content = file.read()file.close()
except FileNotFoundError:print("文件不存在")

在這個例子中:

?

1.??try?塊嘗試打開并讀取?test.txt?文件。

?

2.?如果文件不存在,?open()?函數會引發?FileNotFoundError?異常。

?

3.?程序跳轉到?except?塊,打印“文件不存在”,避免程序崩潰。

?

2.3 捕獲多個異常類型

?

可以使用多個?except?塊處理不同類型的異常:

try:num = int(input("請輸入一個整數:"))result = 10 / num
except ValueError:print("輸入的不是有效的整數")
except ZeroDivisionError:print("除數不能為0")

這里分別捕獲了?ValueError?(輸入非整數)和?ZeroDivisionError?(輸入0作為除數),提供更細致的錯誤反饋。

?

三、擴展異常處理:else與finally子句

?

3.1 else子句:無異常時執行

?

?else?子句緊跟在?except?塊之后,僅在?try?塊未引發任何異常時執行:

try:num = int("10")
except ValueError:print("轉換失敗")
else:print(f"轉換后的整數是:{num}")  # 僅當try塊無異常時執行

else?子句常用于分離正常邏輯和異常處理邏輯,讓代碼結構更清晰。

?

3.2 finally子句:無論如何都會執行

?

?finally?子句用于確保某些代碼始終被執行,無論?try?塊是否引發異常:

file = None
try:file = open('test.txt', 'r')data = file.read()
except FileNotFoundError:print("文件未找到")
finally:if file:file.close()  # 確保文件資源被釋放

在Python 3.4+中,推薦使用?with?語句替代手動?finally?塊關閉文件:

try:with open('test.txt', 'r') as file:data = file.read()
except FileNotFoundError:print("文件未找到")

with?語句會自動管理資源的打開和關閉,相當于隱式的?finally?操作。

?

四、自定義異常:貼合業務需求

?

4.1 為什么需要自定義異常

?

內置異常適用于通用錯誤,但在實際項目中,我們常需根據業務邏輯定義專屬異常。例如在用戶注冊系統中,可能需要處理“用戶名已存在”“密碼格式錯誤”等特定問題,此時自定義異常能讓錯誤處理更清晰。

?

4.2 定義和使用自定義異常

?

自定義異常類通常繼承自?Exception?類或其子類:

class UsernameExistsError(Exception):passdef register_user(username):existing_usernames = ["user1", "user2"]if username in existing_usernames:raise UsernameExistsError(f"用戶名 {username} 已存在")print(f"用戶 {username} 注冊成功")try:register_user("user1")
except UsernameExistsError as e:print(e)

步驟解析:

?

1.?定義?UsernameExistsError?類繼承自?Exception?。

?

2.??register_user?函數在檢測到用戶名重復時,使用?raise?語句拋出異常。

?

3.?外層通過?try - except?捕獲并處理該異常。

?

五、常見問題與解決方案

?

5.1 問題一:捕獲所有異常(過于寬泛)

?

問題描述:使用?except:?捕獲所有異常,包括程序邏輯錯誤和系統退出異常(如?KeyboardInterrupt?),導致錯誤難以排查。

錯誤示例:

try:result = 1 / 0
except:print("發生了錯誤")  # 無法區分具體錯誤類型

解決方案:明確指定異常類型,或使用多個?except?塊分別處理:

try:result = 1 / 0
except ZeroDivisionError:print("除數不能為0")

5.2 問題二:異常丟失

?

問題描述:異常在函數調用鏈中未被正確傳遞或處理,導致無法定位問題根源。

錯誤示例:

def inner_function():return 1 / 0def outer_function():try:inner_function()except:pass  # 異常被“吃掉”,無法定位問題outer_function()

解決方案:使用?raise?重新拋出異常,或記錄日志后再處理:

def inner_function():try:return 1 / 0except ZeroDivisionError:raise  # 重新拋出異常def outer_function():try:inner_function()except ZeroDivisionError:print("捕獲到內層函數的除零異常")outer_function()

5.3 問題三:性能損耗

?

問題描述:頻繁使用異常處理會因棧回溯等操作影響性能。

解決方案:優先使用條件判斷避免異常,僅對真正不可預測的錯誤使用異常處理。例如:

divisor = 0
if divisor != 0:result = 10 / divisor
else:print("除數不能為0")

六、總結:打造健壯的程序

?

掌握異常處理是編寫可靠Python程序的關鍵。通過?try - except?捕獲異常、?else?和?finally?細化邏輯、自定義異常適配業務,再結合對常見問題的規避,我們能夠讓程序在面對意外時優雅應對,而不是突然崩潰。記住:異常處理不是萬能藥,合理的邏輯設計才是減少異常的根本。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/81121.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/81121.shtml
英文地址,請注明出處:http://en.pswp.cn/web/81121.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Groovy:Java 的簡潔版

Groovy 是一種 動態、面向對象的編程語言,運行在 Java 虛擬機(JVM)上,并與 Java 高度兼容。你可以把它理解為“Java 的簡潔版 動態特性 腳本語言的靈活性”。 🧠 Groovy 的核心特點 特性說明? 與 Java 高度兼容可以…

生成模型——PixelRNN與PixelCNN

一、PixelRNN PixelRNN 是一種基于循環神經網絡(RNN)的像素級生成模型,通過逐個像素地生成圖像來構建完整的圖像,其核心思想是將圖像中的像素視為序列,并利用 RNN 的能力來捕捉像素之間的依賴關系。 序列生成&#xf…

每日算法刷題Day14 5.24:leetcode不定長滑動窗口求子數組個數越長越合法4道題,用時1h20min

3. 3325.字符至少出現K次的子字符串I(中等,學習優化) 3325. 字符至少出現 K 次的子字符串 I - 力扣(LeetCode) 思想 1.給你一個字符串 s 和一個整數 k,在 s 的所有子字符串中,請你統計并返回 至少有一個 字符 至少…

怎么判斷一個Android APP使用了Capacitor這個跨端框架

要判斷一個 Android 應用是否使用了 Capacitor 跨端框架,可以通過以下方法逐步驗證: 一、安裝包結構分析 1. 解壓 APK 將 .apk 文件重命名為 .zip 并解壓,檢查以下特征文件: ? assets/public/ 目錄: Capacitor 的核心…

Vue3性能優化: 大規模列表渲染解決方案

# Vue3性能優化: 大規模列表渲染解決方案 一、背景與挑戰 背景 在大規模應用中,Vue3的列表渲染性能一直是開發者關注的焦點。大規模列表渲染往往會導致卡頓、內存占用過高等問題,影響用戶體驗和系統整體性能。 挑戰 渲染大規模列表時,DOM操作…

數據倉庫,掃描量

有五種通用技術用于限制數據的掃描量,正如圖3 - 4所示。第一種技術是掃描那些被打上時戳的數據。當一個應用對記錄的最近一次變化或更改打上時戳時,數據倉庫掃描就能夠很有效地進行,因為日期不相符的數據就接觸不到了。然而,目前的…

反射在spring boot自動配置的應用

目錄 一,背景 二,知識回顧 2.1 理解使用反射技術,讀取配置文件創建目標對象(成員變量,方法,構造方法等) 三,springboot自動配置 3.1 反射在自動配置中的工作流程 3.2 瀏覽源碼…

機器學習 Day1

機器學習概述 機器學習與人工智能、深度學習關系什么是機器學習數據集算法 機器學習與人工智能、深度學習關系 什么是機器學習 機器學習是從數據中自動分析獲取模型,并利用模型對未知數據進行預測。 直觀理解: 所以是從歷史數據中獲取規律,那么這些歷…

Disruptor—2.并發編程相關簡介

大綱 1.并發類容器 2.volatile關鍵字與內存分析 3.Atomic系列類與UnSafe類 4.JUC常用工具類 5.AQS各種鎖與架構核心 6.線程池的最佳使用指南 1.并發類容器 (1)ConcurrentMap (2)CopyOnWrite容器 (3)ArrayBlockingQueue (4)LinkedBlockingQueue (5)SynchronousQueue …

開盤啦 APP 抓包 逆向分析

聲明: 本文章中所有內容僅供學習交流使用,不用于其他任何目的,抓包內容、敏感網址、數據接口等均已做脫敏處理,嚴禁用于商業用途和非法用途,否則由此產生的一切后果均與作者無關! 抓包 這是一個記錄貼。 這個APP是數…

YOLOv8損失函數代碼詳解(示例展示數據變換過程)

本文將展示YOLOv8中損失函數計算的完整代碼解析,注釋中提供了詳盡的解釋,并結合示例演示了數據維度的轉換,以幫助更好地理解。 YOLOv8的損失函數計算代碼位于ultralytics/utils/loss.py文件中(如下所示),我…

微信小程序調用藍牙API “wx.writeBLECharacteristicValue()“ 報 errCode: 10008 的解決方案

1、問題現象 問題:在開發微信小程序藍牙通信功能時,常常會遇到莫名其妙的錯誤,查閱官方文檔可能也無法找到答案。如在寫入藍牙數據時,報了這樣的錯誤: {errno: 1500104, errCode: 10008, errMsg: "writeBLECharacteristicValue:fail:system error, status: UNKNOW…

軟考 UML中的 用例圖 的泛化 包含 擴展 關系

用例圖的泛化、擴展和包含 - ^_^肥仔John - 博客園

MyBatis-Plus的自帶分頁方法生成的SQL失敗:The error occurred while setting parameters

1、error描述 數據庫是postgres,Java使用mybatis-plus的分頁功能,生成的分頁SQL不能正常運行。 "msg": "nested exception is org.apache.ibatis.exceptions.PersistenceException: Error querying database. Cause: com.baomidou.my…

Redis從入門到實戰 - 原理篇

一、數據結構 1. 動態字符串SDS 我們都知道Redis中保存的key是字符串,value往往是字符串或者字符串的集合。可見字符串是Redis中最常用的一種數據結構。 不過Redis沒有直接使用C語言中的字符串,因為C語言字符串存在很多問題: 獲取字符串長…

人形機器人通過觀看視頻學習人類動作的技術可行性與前景展望

摘要 本文深入探討人形機器人通過觀看視頻學習人類動作這一技術路線的正確性與深遠潛力。首先闡述該技術路線在模仿人類學習過程方面的優勢,包括對人類動作、表情、發音及情感模仿的可行性與實現路徑。接著從技術原理、大數據訓練基礎、與人類學習速度對比等角度論證…

高分辨率北半球多年凍土數據集(2000-2016)

關鍵數據集分類&#xff1a;冰凍圈數據集時間分辨率&#xff1a;10 year < x < 100 year空間分辨率&#xff1a;1km - 10km共享方式&#xff1a;開放獲取數據大小&#xff1a;339.79 MB數據時間范圍&#xff1a;2000-01-01 — 2016-12-31元數據更新時間&#xff1a;2022-…

零售智能執行大模型架構設計:從空間建模到上下文推理,再到智能Agent

零售智能執行大模型架構設計&#xff1a;從空間建模到上下文推理&#xff0c;再到智能Agent &#x1f9e0; 引言&#xff1a;零售智能執行的再定義 在傳統零售執行中&#xff0c;面對SKU數量龐雜、貨架布置多變、陳列標準難以落地等問題&#xff0c;靠人力巡檢或輕量識別模型已…

RIP 協議實驗全記錄:從配置到問題解決

在網絡世界中&#xff0c;路由協議就像是交通指揮員&#xff0c;引導數據在不同網絡之間順暢傳輸。今天&#xff0c;我們就來深入探索 RIP&#xff08;Routing Information Protocol&#xff09;協議&#xff0c;通過一系列實驗&#xff0c;揭開它的神秘面紗&#xff01; 一、搭…

基于SpringBoot的網上租賃系統設計與實現

項目簡介 本項目是基于 Spring Boot Vue 技術棧開發的 網上租賃系統。該系統通過前后端分離的架構&#xff0c;提供用戶和管理員兩種角色的操作權限&#xff0c;方便用戶進行商品租賃、訂單管理、信息查詢等操作&#xff0c;同時也為管理員提供了商品管理、用戶管理、訂單管理…