iT邦幫忙

2024 iThome 鐵人賽

DAY 17
0
Python

初學者的 30 天 Python 復健課程系列 第 17

復健第十七天:寫程式就是一場錯誤 Type Errors 的冒險

  • 分享至 

  • xImage
  •  

好啦,標題是聳動了點,不過確實在學習程式語言的路上,便是不斷地和錯誤打交道,我們透過解決錯誤,進而學習更多的知識,並且讓應用程式運作起來。

所以與其說我們在記憶更多的語法,不如說,我們為了解決這些冒出的錯誤,進而創造出更多的方法,因此理解程式語言中的各種錯誤類型,並且學會辨識不同的錯誤,可以幫助我們快速地思考相對應合適的解決辦法,讓我們成為更好的工程師。

Python 有哪些錯誤類型?

當我們編寫 Python 或是其他的程式語言時,常常會遇到一些打字錯誤或其他的錯誤,而這些錯誤如果造成程式無法執行時,Python 會顯示一個錯誤訊息,提供我們問題發生的位置及錯誤的類型的相關資訊,有時還會給出解決方案的建議,只能說工程師偷懶歸偷懶,該貼心的時候還是蠻貼心的。(真暖!)

在終端畫面中輸入 python 並啟動 Python interactive shell,然後讓我們嘗試重現 Python 常見的錯誤類型。

SyntaxError(語法錯誤)

>>> print 'hello world'
  File "<stdin>", line 1
    print 'hello world'
    ^^^^^^^^^^^^^^^^^^^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?

如上所示,Python 告知我們犯了一個語法錯誤 SyntaxError,因為我們忘記在 print 語句中加上括號 (),同時 Python 也很貼心地提示了我們解決方法。

根據 Python 的提示,我們得以修正這個錯誤,並且讓 Python 輸出 'hello world' 的字串。

>>> print('hello world')
hello world

NameError(名稱錯誤)

>>> print(age)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'age' is not defined

根據錯誤訊息的提示,這邊指出變數 age 沒有定義,而我們在沒有定義 age 變數狀況下,卻嘗試將其 print 輸出。

為了要解決 NameError 這個問題,我們先定義變數 age 並賦值,這樣便可以順利印出 age 的值。

>>> age = 25
>>> print(age)
25

IndexError(索引錯誤)

>>> numbers = [1, 2, 3, 4, 5]
>>> numbers[5]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

由於這個串列的索引範圍是 0 到 4,而我們嘗試的索引值為 5,超出可以存取範圍的索引值,Python 因此拋出了 IndexError 的錯誤訊息。

ModuleNotFoundError(模組找不到錯誤)

>>> import maths
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'maths'

為了引發這個錯誤,我們故意在 math 模組名稱中多加了一個 s,因此引發了 ModuleNotFoundError,所以只需移除多餘的 s 即可解決問題。

>>> import math

問題修正後,我們可以使用 math 模組中的各種函數了。

AttributeError(屬性錯誤)

>>> import math
>>> math.PI
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'math' has no attribute 'PI'. Did you mean: 'pi'?

如 Python 的提示,我們引發了 AttributeError 的錯誤,因為在 math 模組中,並不存在 PI,為了要修正這個錯誤,我們應該使用 pi,所以只需將 PI 修正為 pi 就可以解決這個錯誤了。

>>> import math
>>> math.pi
3.141592653589793

KeyError(鍵錯誤)

>>> users = {'name':'Frank', 'age':250, 'country':'Taiwan'}
>>> users['name']
'Asab'
>>> users['county']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'county'

如上所示,當我們試圖存取字典 dictionary 裡面的鍵時,由於不小心將 country 拼成了 county,Python 因此拋出了 KeyError 的錯誤訊息,這就沒什麼好說的,把字打對就能解決了。

>>> users = {'name':'Frank', 'age':250, 'country':'Taiwan'}
>>> users['name']
'Asab'
>>> users['country']
'Taiwan'

TypeError(類型錯誤)

>>> 4 + "3"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

在 Python 中,我們無法將不同類型的資料型態(如:數字 int 與字串 str)進行相加運算,因此引發了 TypeError 的錯誤訊息。為了解決這個錯誤,我們可以將字串 string 轉換為整數 integer或浮點數 float,或者將數字轉換為字串。

>>> 4 + int("3")
7
>>> 4 + float("3")
7.0
>>> str(4) + "3"
'43'

ImportError(匯入錯誤)

>>> from math import power
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 'power' from 'math' (/opt/homebrew/Cellar/python@3.12/3.12.4/Frameworks/Python.framework/Versions/3.12/lib/python3.12/lib-dynload/math.cpython-312-darwin.so)

在 Python 內建的 math 模組中,並沒有 power 函數,所以 from math import power 會引發 ImportError 告知我們這個 import 行為是無法正常運作的。

如果想要修正這個問題,實際上的函數名稱應該是 pow,只要將 power 改為 pow 就正常了。

>>> from math import pow
>>> pow(2, 3)
8.0

ValueError(值錯誤)

>>> int("12a")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '12a'

在這個範例中,我們無法將字串轉換為數字,因為其中包含字母 'a'

ZeroDivisionError(除以零錯誤)

>>> 1/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

我們無法用 0 來除以任何數字,這會引發 ZeroDivisionError

後記

有一句我很喜歡的話:「我們永遠不可能知道自己不知道的事。」透過別人的試錯與解答,我們得以累積相關經驗,下次再遇到這些錯誤的時候,也能很快知道解決辦法,畢竟不經一事不長一智嘛!


上一篇
復健第十六天:聽起來好像很困難的 Lambda 函式
下一篇
復健第十八天:操控時間是一種超能力——datetime 模組
系列文
初學者的 30 天 Python 復健課程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言