不間斷 Python 挑戰 Day 33 - 異常處理

閱讀時間約 15 分鐘
不管你是程式的新手或老手,不管你是不是第一天寫Python程式,在編譯或執行時絕對有出現程式錯誤或異常的時候,也就是俗稱的「bug」,這對於程式編譯人員是好事,你可以在程式撰寫階段就事先排除這些異常,或是加上捕捉異常的程式區段以及處理程序,讓程式即使出現異常也可以繼續執行。因此,首先我們可以先來看一下常見的異常事件有哪些,相信寫過Python程式的人,很多都已經遇過了。

常見異常事件

AttributionError:物件沒有這個屬性
Exception:通用型的錯誤事件
FileNotFoundError:找不到open()開啟的檔案
FloatingPointError:浮點計算錯誤
ImportError:匯入模組或物件失敗
IndentationError:縮排錯誤
IndexError:索引超出範圍
IOError:輸入/輸出操作失敗
KeyError:不存在這個鍵
MemoryError:記憶體溢位
NameError:物件未宣告
OverflowError:數值運算超出最大限制
SyntaxError:語法錯誤
SystemError:直譯器的系統錯誤
TypeError:資料型別錯誤
ValueError:傳入無效的參數
ZeroDivisionError:除數為0
以下我們來舉一些常見的異常事件,看一下Python的Traceback會告訴我們什麼訊息。

FileNotFoundError

嘗試開啟一個程式路徑底下找不到的檔案會出現FileNotFoundError。
# FileNotFoundError
with open("file.txt", "r") as file:
  file.read()
這時Python的Traceback會列出異常報告,告訴我們錯誤出現在哪個檔案的第幾行,以及錯誤的類型和說明。如以下,報告中明確指出了Python直譯器發現在「main.py」的「with open("file.txt", "r") as file:」這一行出現了錯誤,錯誤的類型是「FileNotFoundError」,原因是「No such file or directory: 'file.txt'」,並沒有存在「file.txt」這個檔案讓程式開啟。
Traceback (most recent call last):
File "C:\Users\wjweng\PycharmProjects\marathon_python\Day33\main.py", line 2, in
with open("file.txt", "r") as file:
FileNotFoundError: [Errno 2] No such file or directory: 'file.txt'

KeyError

嘗試透過字典中不存在的鍵來取得值會出現KeyError。
# KeyError
dictionary = {"台北市": 100}
value = dictionary["新北市"]
dictionary這個字典僅存在"台北市": 100這樣一組鍵值對,當我們試圖使用不存在的"新北市"做為鍵來取值便會出現錯誤,Traceback訊息如下:
Traceback (most recent call last):
  File "C:\Users\wjweng\PycharmProjects\marathon_python\Day33\main.py", line 2, in 
    value = dictionary["新北市"]
KeyError: '新北市'

IndexError

使用超出串列範圍的索引值來存取串列內容會出現IndexError。
# IndexError
city_list = ["台北市", "新北市", "台中市"]
city = city_list[3]
串列city_list存在三個元素,索引值範圍為0~2,當使用3做為索引來取用串列值會出現錯誤,Traceback訊息如下:
Traceback (most recent call last):
  File "C:\Users\wjweng\PycharmProjects\marathon_python\Day33\main.py", line 2, in 
    city = city_list[3]
IndexError: list index out of range

TypeError

使用非預期的資料型別來做操作會出現TypeError。
# TypeError
text = "大家好"
print(text + 1)
上述程式使用字串型別的變數text來做加法運算,因兩者資料型別不一致而無法執行,Traceback訊息如下:
Traceback (most recent call last):
  File "C:\Users\wjweng\PycharmProjects\marathon_python\Day33\main.py", line 2, in 
    print(text + 1)
TypeError: can only concatenate str (not "int") to str

異常處理程序

try - except

try - except語句為最基本的異常處理程序,try語句區塊中為可能需要捕捉異常情況的指令,except語句區塊為當異常情況發生時的處理方式,語法如下:
try:
  可能需要捕捉異常情況的指令
except:
  異常情況發生時的處理方式
如以下範例,我們將前述IndexError的範例程式放入try語塊,並在except中捕捉IndexError,當出現這項錯誤時,會執行except語塊中的內容,避免程式因錯誤而終止。
def print_city(index):
  city_list = ["台北市", "新北市", "台中市"]

  try:
    city = city_list[index]
  except IndexError:
    print("索引值超出範圍!")

print_city(3)
執行結果:
索引值超出範圍!

try - except - else

此語法在try - except語句下又擴充了else指令,當try語塊中的指令執行正常時,便會執行else語塊中的內容,擴充後的語法如下:
try:
  可能需要捕捉異常情況的指令
except:
  異常情況發生時的處理方式
else:
  指令正確執行時的處理方式
以下程式中,0可以做為索引值來取得city_list的元素,因此程式會跳過except區塊,直接執行else區塊的內容。
def print_city(index):
  city_list = ["台北市", "新北市", "台中市"]

  try:
    city = city_list[index]
  except IndexError:
    print("索引值超出範圍")
  else:
    print(city)

print_city(0)
執行結果:
台北市

try - except - else - finally

finally指令放在異常處理程序的最後方,區塊內放置無論是否有異常情況發生都會執行的內容,完整的語法如下:
try:
  可能需要捕捉異常情況的指令
except:
  異常情況發生時的處理方式
else:
  指令正確執行時的處理方式
finally:
  程式正常或異常皆會執行的指令
以下範例除了增加了finally區塊外,其餘同上述程式,執行後會多印出finally區塊的內容。
def print_city(index):
  city_list = ["台北市", "新北市", "台中市"]

  try:
    city = city_list[index]
  except IndexError:
    print("索引值超出範圍")
  else:
    print(city)
  finally:
    print("執行完畢!")

print_city(0)
執行結果:
台北市
執行完畢!

捕捉多個異常

若預期的錯誤可能不只一種,可以設計多個except區塊捕捉不同的異常,或是在一個except區塊內來捕捉多個異常。
  • 使用多個except區塊捕捉不同的異常,語法如下:
try:
  可能需要捕捉異常情況的指令
except 異常事件1:
  異常事件1發生時的處理方式
except 異常事件2:
  異常事件2發生時的處理方式
......
延續之前的範例,除了原有的IndexError以外,新增捕捉TypeError,當print_city()輸入的參數為3及"a"時,分別跳出不同的錯誤訊息。
def print_city(index):
  city_list = ["台北市", "新北市", "台中市"]

  try:
    city = city_list[index]
  except IndexError:
    print("索引值超出範圍!")
  except TypeError:
    print("型別錯誤!")
  else:
    print(city)
  finally:
    print("執行完畢!")

print_city(3)
print_city("a")
執行結果:
索引值超出範圍!
執行完畢!
型別錯誤!
執行完畢!
  • 使用一個except區塊捕捉多個異常,語法如下:
try:
  可能需要捕捉異常情況的指令
except (異常事件1, 異常事件2, ......):
  異常事件發生時的處理方式
重新設計上個範例,將IndexError及TypeError放在同一個except區塊裡面,但此種寫法便無法區隔是哪一種異常事件導致錯誤發生。
def print_city(index):
  city_list = ["台北市", "新北市", "台中市"]

  try:
    city = city_list[index]
  except (IndexError, TypeError):
    print("索引值超出範圍 或 型別錯誤!")
  else:
    print(city)
  finally:
    print("執行完畢!")

print_city(3)
print_city("a")
執行結果:
索引值超出範圍 或 型別錯誤!
執行完畢!
索引值超出範圍 或 型別錯誤!
執行完畢!

使用內建錯誤訊息

針對上述無法區分異常事件的情況,我們可以導出Python內建的錯誤訊息,來協助分辨錯誤的類型,語法如下:
try:
  可能需要捕捉異常情況的指令
except (異常事件1, 異常事件2, ......) as error_message:
  異常事件發生時的處理方式
改良上述程式,使用error_message將錯誤訊息儲存起來,就可以在發生IndexError時,印出「list index out of range」,而在發生TypeError時,印出「list indices must be integers or slices, not str」等不同的錯誤訊息。
def print_city(index):
  city_list = ["台北市", "新北市", "台中市"]

  try:
    city = city_list[index]
  except (IndexError, TypeError) as error_message:
    print(f"{error_message}")
  else:
    print(city)
  finally:
    print("執行完畢!")

print_city(3)
print_city("a")
執行結果:
list index out of range
執行完畢!
list indices must be integers or slices, not str
執行完畢!

自定義異常

除了讓Python直譯器自行判斷異常外,我們也可以使用raise語法自行定義異常事件,這個異常事件可以是Python判斷為正常的情況。如以下的程式碼中,我們把索引值大於1就定義為異常,但實際上索引值為2對於Python而言也是合理的。
def print_city(index):
  city_list = ["台北市", "新北市", "台中市"]

  if index > 1:
    raise IndexError("索引值超出範圍")

print_city(3)
執行後,Python會根據我們所自定義的異常事件來丟出Traceback訊息。
Traceback (most recent call last):
  File "C:\Users\wjweng\PycharmProjects\marathon_python\Day33\main.py", line 6, in 
    print_city(2)
  File "C:\Users\wjweng\PycharmProjects\marathon_python\Day33\main.py", line 4, in print_city
    raise IndexError("索引值超出自訂範圍")
IndexError: 索引值超出自訂範圍
定義了異常事件後,我們同樣可以使用上面提過的所有異常處理程序來處理自定義的異常事件,這裡就不再多重覆一次。

總結

俗話說「怕熱就不要進廚房」,對於寫程式的人來說,沒有遇過或解過bug的就不算真正寫過程式,重要的是如何培養debug的能力,以及如何對於可能預期的異常事件做出對應的預防處理。本篇算是這系列文章首次對於異常事件做初步的介紹,除了列出一些初學者常遇到的異常事件外,也說明了Python對於異常事件的處理程序,讓我們在寫作程式時,能減少一些讓程式異常終止的機會,增加一些容錯的能力。

程式範例

為什麼會看到廣告
46會員
36內容數
留言0
查看全部
發表第一個留言支持創作者!
Wei-Jie Weng的沙龍 的其他內容
在先前的文章中,我們曾經實做過文字介面版本的密碼產生器,這篇文章中,我們將添加新的功能,包括記錄密碼使用場域的名稱、網址、帳號等,並能夠將以上記錄存檔,當然最重要的是將它轉換成友善的圖形介面。
繼上一篇文章介紹了多種tkinter的視窗元件後,這篇我們再來討論三種視窗元件的配置方法以及優缺點,以適當移動各個元件到視窗中指定的位置,讓整個視窗版面的配置看起來更合理且美觀。
之前的文章中介紹過了Turtle Graphics,它是架構於tkinter模組之上以實現基本圖形介面的繪圖模組,這篇文章就來說明tkinter模組常用元件(widget)的基本用法,以及如何用它來設計出一個具有圖形使用者介面(Graphical User Interface, GUI)的程式。
在上一篇的文章中,我們提到關於開啟CSV文件的方式,從單純的當作純文字文件開啟,到引入Python內建的csv模組對CSV類型的檔案做基本的讀寫操作,在這篇文章中,我們將再進一步使用Pandas這套強大的工具,來簡化CSV文件處理的流程。
CSV全名為Comma-Separated Values,中文稱為逗號分隔值,也可稱為字元分隔值,因為分隔字元也可以不是逗號。它以純文字的形式儲存表格資料,同一列的資料以逗號或其它符號分隔成不同欄位,每一列的資料間以換行符號分隔。網路上很多資料的格式都是以CSV檔案呈現,例如交通部中央氣象局的觀測資
到目前為止,我們都還是在附檔名為.py的Python檔案執行程式碼,當程式需要與外部的檔案互動,例如讀取文字、表格、或是影像來做分析,或是把程式執行的結果儲存下來,就需要能夠存取外部的檔案。例如,在上一節中,當貪食蛇遊戲結束之後,隨著程式停止執行,該次的分數也就被丟棄,若能將分數記錄下來,下次遊戲開
在先前的文章中,我們曾經實做過文字介面版本的密碼產生器,這篇文章中,我們將添加新的功能,包括記錄密碼使用場域的名稱、網址、帳號等,並能夠將以上記錄存檔,當然最重要的是將它轉換成友善的圖形介面。
繼上一篇文章介紹了多種tkinter的視窗元件後,這篇我們再來討論三種視窗元件的配置方法以及優缺點,以適當移動各個元件到視窗中指定的位置,讓整個視窗版面的配置看起來更合理且美觀。
之前的文章中介紹過了Turtle Graphics,它是架構於tkinter模組之上以實現基本圖形介面的繪圖模組,這篇文章就來說明tkinter模組常用元件(widget)的基本用法,以及如何用它來設計出一個具有圖形使用者介面(Graphical User Interface, GUI)的程式。
在上一篇的文章中,我們提到關於開啟CSV文件的方式,從單純的當作純文字文件開啟,到引入Python內建的csv模組對CSV類型的檔案做基本的讀寫操作,在這篇文章中,我們將再進一步使用Pandas這套強大的工具,來簡化CSV文件處理的流程。
CSV全名為Comma-Separated Values,中文稱為逗號分隔值,也可稱為字元分隔值,因為分隔字元也可以不是逗號。它以純文字的形式儲存表格資料,同一列的資料以逗號或其它符號分隔成不同欄位,每一列的資料間以換行符號分隔。網路上很多資料的格式都是以CSV檔案呈現,例如交通部中央氣象局的觀測資
到目前為止,我們都還是在附檔名為.py的Python檔案執行程式碼,當程式需要與外部的檔案互動,例如讀取文字、表格、或是影像來做分析,或是把程式執行的結果儲存下來,就需要能夠存取外部的檔案。例如,在上一節中,當貪食蛇遊戲結束之後,隨著程式停止執行,該次的分數也就被丟棄,若能將分數記錄下來,下次遊戲開
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
十年前,我跟小悟參加了台南政府所舉辦的 24 小時不間斷進食比賽,當年,我以兩分之差,沒擠進金榜。在挑戰時間內,來不及吃狀元糕跟芋頭八寶冰,以致失掉食物王的頭銜。十年後,小悟說,要不要再來回味當年勇?我知道,年輕的我胃袋能撐船,可逝去的青春,最先反映在食慾上。我笑著說不了......
Thumbnail
持著前作的風格,《蜘蛛人:穿越新宇宙》在色彩或畫面的呈現上依舊大膽、前衛,並且嘗試藉由多重宇宙的「優勢」,在成長動畫的既有敘事上,嘗試更多不同的可能性。精彩的安排讓觀看這部作品讓成為十足的享受,並賦予了觀眾再次進場支持的充分動機。
Thumbnail
節目這邊聽 📎錄製時間: 2023.10 汪汪隊立大功! MRT(Mission Readiness Test)是難度最高的國際搜救犬認證! 但是我們有兩位英雄(一人一汪)順利通過這次的認證,拿到了優良的成績! 讓我們歡迎領犬員羅浩芳!就讓她帶著小編、江小姐還有各位聽眾,一起了解這次搜救犬
Thumbnail
這一陣子不少投資標的都在上漲 連成長性沒有科技股強的食品股也在慢慢上升中 今天記錄一下自己食品股大成的最新績效 身為雞肉雙雄的其中一雄 除了飼料、雞肉、雞蛋以外,還跨足了沙拉油、豬肉、海鮮、餐廳等事業體 幾乎可說是一檔食品ETF(還不用付管理費),進去它的官網就可以看到許多不同的事業體
Thumbnail
你現在也許單一個句子可以說得溜,但持續說話覺得尷尬的原因在於:缺乏連接詞。好的連接詞會讓口語表達更精確有力,讓韓國人聽到你說的話不需要猜測意思或重新思考,表達能力也就跟著上升!
Thumbnail
喜歡音樂的羅小咩,不定期將在周六中午12:00與你聊聊戲劇中的音樂,還有音樂中的戲劇。本次介紹:惡作劇之吻、慶餘年、Good Casting、溫柔時光、鋼之鍊金術師這五個戲劇作品的主題曲。
Thumbnail
喜歡音樂的羅小咩,不定期將在周六中午12:00與你聊聊戲劇中的音樂,還有音樂中的戲劇。本次介紹:必娶女人、kill me heal me、錦衣之下、101次求婚、灌籃高手這五個戲劇作品的主題曲。
近期許多地方受到洪水以及颱風的侵襲 但包你發的線路及網路穩定度完全不受到影響 大家可以放心,我們是24小時全年無休不間斷 就算你半夜三點要玩包你發也完全OK 不會像有些系統只在白天開放 而同樣的穩定度也是一大考驗 在這種供電不穩定的情況 也有可能導致其他遊戲斷線 但包你發機房穩定、有備用電源 完全不
Thumbnail
疫情長時間帶來了減少開放性的社交機會,最直接的影響莫過於情緒勒索造成的封閉性失調,感謝國立台灣戲曲學院傑出校友,為身心障礙的大寶寶們帶來一系列精彩的演出,透過精心策劃的舞蹈及雜耍表演,帶給住民體驗了跟以往不同的志工服務內容,見到了久違住民
Thumbnail
每一次TDCA的關愛陪伴,都讓受贈的服務對象感受到滿滿的幸福感,一起協力完成手作皮革鑰匙圈,每一針每一線都在訓練孩子們手眼協調的肢體,透過不同花色皮革來搭配,不僅訓練孩子對色彩的辨識能力,同時也在培養眼界裡的審美觀噢!
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
十年前,我跟小悟參加了台南政府所舉辦的 24 小時不間斷進食比賽,當年,我以兩分之差,沒擠進金榜。在挑戰時間內,來不及吃狀元糕跟芋頭八寶冰,以致失掉食物王的頭銜。十年後,小悟說,要不要再來回味當年勇?我知道,年輕的我胃袋能撐船,可逝去的青春,最先反映在食慾上。我笑著說不了......
Thumbnail
持著前作的風格,《蜘蛛人:穿越新宇宙》在色彩或畫面的呈現上依舊大膽、前衛,並且嘗試藉由多重宇宙的「優勢」,在成長動畫的既有敘事上,嘗試更多不同的可能性。精彩的安排讓觀看這部作品讓成為十足的享受,並賦予了觀眾再次進場支持的充分動機。
Thumbnail
節目這邊聽 📎錄製時間: 2023.10 汪汪隊立大功! MRT(Mission Readiness Test)是難度最高的國際搜救犬認證! 但是我們有兩位英雄(一人一汪)順利通過這次的認證,拿到了優良的成績! 讓我們歡迎領犬員羅浩芳!就讓她帶著小編、江小姐還有各位聽眾,一起了解這次搜救犬
Thumbnail
這一陣子不少投資標的都在上漲 連成長性沒有科技股強的食品股也在慢慢上升中 今天記錄一下自己食品股大成的最新績效 身為雞肉雙雄的其中一雄 除了飼料、雞肉、雞蛋以外,還跨足了沙拉油、豬肉、海鮮、餐廳等事業體 幾乎可說是一檔食品ETF(還不用付管理費),進去它的官網就可以看到許多不同的事業體
Thumbnail
你現在也許單一個句子可以說得溜,但持續說話覺得尷尬的原因在於:缺乏連接詞。好的連接詞會讓口語表達更精確有力,讓韓國人聽到你說的話不需要猜測意思或重新思考,表達能力也就跟著上升!
Thumbnail
喜歡音樂的羅小咩,不定期將在周六中午12:00與你聊聊戲劇中的音樂,還有音樂中的戲劇。本次介紹:惡作劇之吻、慶餘年、Good Casting、溫柔時光、鋼之鍊金術師這五個戲劇作品的主題曲。
Thumbnail
喜歡音樂的羅小咩,不定期將在周六中午12:00與你聊聊戲劇中的音樂,還有音樂中的戲劇。本次介紹:必娶女人、kill me heal me、錦衣之下、101次求婚、灌籃高手這五個戲劇作品的主題曲。
近期許多地方受到洪水以及颱風的侵襲 但包你發的線路及網路穩定度完全不受到影響 大家可以放心,我們是24小時全年無休不間斷 就算你半夜三點要玩包你發也完全OK 不會像有些系統只在白天開放 而同樣的穩定度也是一大考驗 在這種供電不穩定的情況 也有可能導致其他遊戲斷線 但包你發機房穩定、有備用電源 完全不
Thumbnail
疫情長時間帶來了減少開放性的社交機會,最直接的影響莫過於情緒勒索造成的封閉性失調,感謝國立台灣戲曲學院傑出校友,為身心障礙的大寶寶們帶來一系列精彩的演出,透過精心策劃的舞蹈及雜耍表演,帶給住民體驗了跟以往不同的志工服務內容,見到了久違住民
Thumbnail
每一次TDCA的關愛陪伴,都讓受贈的服務對象感受到滿滿的幸福感,一起協力完成手作皮革鑰匙圈,每一針每一線都在訓練孩子們手眼協調的肢體,透過不同花色皮革來搭配,不僅訓練孩子對色彩的辨識能力,同時也在培養眼界裡的審美觀噢!