💡 先搞懂問題
晴空咖啡的店長學了兩堂 Python,想寫一支小程式:問客人要買幾杯拿鐵,再算出總價。他寫了 cups = input("要買幾杯?"),接著 total = cups * 45。執行後輸入 3,畫面上沒有出現 135,而是一長串 333333…,數一數剛好 45 個 3。他改成先加運費 cups + 10,這次程式直接停下來,印出一行看不懂的 TypeError。另外他也發現,print(10 / 2) 印出來是 5.0,多了一個小數點。
這三件怪事的原因是同一個:Python 裡的每一筆資料都有「種類」,叫做型別(type)。數字 3 和用引號包起來的文字 "3" 長得很像,型別卻完全不同;同一個 * 或 +,碰到不同型別的資料,意思就不一樣,有時候根本不允許。而 input()(讓使用者從鍵盤打字的函式)交回來的,永遠是文字。
生活比喻:點餐單上的字,和真正的杯數
想像晴空咖啡的外場服務生幫客人點餐,在點餐單上寫下「拿鐵 3」。這張單子上的「3」只是筆寫的一個字。櫃台要算錢時,店員得先看懂這個字,在心裡把它當成「3 杯」,再乘上單價 45 元,算出 135 元。
如果有個新來的店員完全照字面操作呢?叫他「把單子上的 3 乘以 45」,他把那個字影印了 45 次,排成一長串 3;叫他「把單子上的 3 加上 10 元運費」,他就愣住了:是要在紙上再寫一個 10,還是把杯數加 10?這種說不清楚的要求,他乾脆不做。單子上如果寫的是「2.5」,要他照「整杯數」來讀,他也讀不出來,因為整杯數不會有小數點。
str);心裡讀出來的杯數是整數(integer,int),帶小數點的量是浮點數(floating-point number,float)。外場服務生就是 input():客人說什麼,它交回來的都是寫在單子上的字。「看懂字、讀成數量」對應 int() 與 float(),反過來把數量寫成字是 str()。那位照字面操作的新店員,就是完全不會替你猜意思的 Python:"3" * 45 是把文字重複 45 次,"3" + 10 直接報錯。
比喻有三個地方和實際不同。第一,真實的店員看到「3」自然會當成 3 杯,Python 不會自動幫你轉換,一定要你自己寫 int(...)。第二,轉換不會把原本的字串「改掉」:cups = int(text) 是算出一個新的整數物件,再把名字 cups 貼上去,原本的 '3' 還在,text 也還貼在它上面。第三,紙上寫的 2.5 是精確的,電腦裡的浮點數卻是近似值,原理補完會用 0.1 + 0.2 說明。
型別屬於物件,不屬於名字
第 2 課說過,x = 5 是先算出右邊的值,再把名字 x 這張標籤貼到那個物件(object,記憶體裡真正的那筆資料)上。型別是物件本身的屬性:整數物件永遠是整數,名字只是標籤,撕下來改貼到字串上也可以。這一課會遇到五種最基本的型別:
int 整數,例如 45、-3、0;float 浮點數,就是有小數點的數,例如 45.0、2.5;str 字串,用引號包起來的文字,例如 "拿鐵"、"3";bool 布林值(boolean),只有 True(是)和 False(否)兩個值,第 7 課的條件判斷會大量用到;None 代表「沒有值」,例如還沒選優惠券。想知道某個物件是什麼型別,用 type(…),它會回答 <class 'int'> 這樣的字,意思是「整數型別」。
🎮 互動實驗室一:每個物件都有自己的型別
下面是一段真的用 Python 3.13 執行過的程式:晴空咖啡一杯拿鐵 45 元,客人買 3 杯。按「下一步」一次執行一行,右邊會畫出每個名字貼到哪個物件、物件是什麼型別。綠色箭頭 ➜ 指著「下一個要執行」的行;遇到 🤔 問題時先猜再按下一步,自動播放也會在那裡停下來等你。
45.0,物件上方寫著「浮點數 float」,和最上面的 45(整數 int)是兩個不同的物件。135 / 3 明明剛好整除,用 / 算出來的還是浮點數。接著看第 7、8 行:// 和 % 算出的 2 和 35 又回到整數。最後兩行的 True、None 是橘色框,它們也是物件,名字同樣是用箭頭貼上去的。🎮 互動實驗室二:input() 拿到的是字串
這次程式會用 input() 問「要買幾杯?」。播放器沒辦法真的讓你打字,所以準備了四種情況,用右上角的選單切換:使用者打 3 或 2.5,程式有轉換或忘了轉換。每一種都是 Python 3.13 真的執行出來的結果,包括錯誤訊息。
text 都貼在綠框的字串上。① 和 ④ 只差在第 3 行用 int() 還是 float();② 的 text * 3 印出 333,程式沒有任何警告,下一行的 + 才出錯;③ 的錯誤類型不同,是 ValueError:型別沒問題,是字串的內容讀不成整數。出錯的那一步,下方輸出畫面會出現紅字的錯誤訊息(Traceback),最後一行就是錯誤類型和原因。🎮 互動實驗室三:先猜再執行,12 張預測輸出卡
每張卡是一行程式,請先選出你認為畫面會印出什麼,再看 Python 3.13 實際的輸出和原因。如果會出錯,就選錯誤的名稱。答完按「下一張」,全部做完會顯示答對幾張;隨時可以按「重來」。
📘 原理補完
正式名稱與官方用語
Python 官方文件把語言本身提供的資料種類叫做內建型別(built-in types)。這一課的 int 與 float 屬於數值型別(numeric types),str 是文字序列型別(text sequence type),bool 只有 True、False 兩個值,None 則是 NoneType 這個型別唯一的值。+、* 這類符號叫運算子(operator),被運算的兩邊叫運算元(operand),整串 price * cups 叫做運算式(expression):運算式會被算成一個值,也就是一個物件。
大家常說的「轉型」(type conversion),在 Python 裡其實是「用型別的名字建立一個新物件」:int("42") 是請 int 這個型別根據字串 "42" 做出一個整數。所以轉型永遠產生新物件,不會改掉原本的東西。
算術運算子一覽
下表的結果都用 Python 3.13 實際算過。最常被問的是第四到第六列:/ 一律得到浮點數;// 是整除(floor division),只留下商往下取的整數;% 是取餘數(modulo)。整數和浮點數混在一起算時,結果是浮點數。
| 運算子 | 名稱 | 例子 | 結果 | 結果型別 | 說明 |
|---|---|---|---|---|---|
+ | 加 | 7 + 2 | 9 | int | 兩邊都是整數,結果是整數 |
- | 減 | 7 - 2 | 5 | int | |
* | 乘 | 7 * 2 | 14 | int | 鍵盤沒有 ×,用星號 |
/ | 除 | 7 / 2、6 / 3 | 3.5、2.0 | float | 一定是 float,剛好整除也一樣 |
// | 整除 | 7 // 2 | 3 | int | 只要商的整數部分(往下取) |
% | 取餘數 | 7 % 2 | 1 | int | 常用來判斷奇偶、找零 |
** | 次方 | 7 ** 2 | 49 | int | 不是 ^ |
+(混合) | 加 | 7 + 2.0 | 9.0 | float | 有一邊是 float,結果就是 float |
+(字串) | 串接 | "ab" + "cd" | 'abcd' | str | 兩邊都要是字串 |
*(字串) | 重複 | "ab" * 3 | 'ababab' | str | 字串乘整數 |
運算順序(優先順序)
一行算式裡有好幾個運算子時,Python 依照運算子優先順序(operator precedence)決定先算哪個,規則和數學課差不多:先算括號,再算 **,接著是 *、/、//、%,最後是 +、-;同一級的從左算到右,所以 10 - 4 - 3 是 3。不確定時就加括號,括號不會讓程式變慢,還能讓讀的人一眼看懂。
型別轉換:int()、float()、str()
轉換函式都是「讀一個物件、做出一個新物件」。最容易出事的是 int():它看得懂整數寫法的文字(前後的空白可以),看不懂小數點;用在浮點數上則是直接去掉小數部分,不是四捨五入。
| 寫法 | 結果 | 結果型別 | 說明 |
|---|---|---|---|
int("42") | 42 | int | 文字讀成整數 |
int(" 7 ") | 7 | int | 前後空白會被忽略 |
int("3.5") | ValueError | — | 有小數點的文字,int() 讀不懂 |
int(3.9) | 3 | int | 浮點數轉整數:直接去掉小數,不會變 4 |
float("3.5") | 3.5 | float | 帶小數的文字要用 float() |
float("3") | 3.0 | float | 整數寫法的文字也可以 |
float("abc") | ValueError | — | 不是數字的文字 |
str(135) | '135' | str | 數字寫成文字,才能和其他字串用 + 接起來 |
常見錯誤與錯誤訊息的長相
下面的訊息都是 Python 3.13 實際印出來的。最後一行最重要:冒號前面是錯誤類型,後面是原因。File "main.py", line 2 告訴你出錯的檔案和行號(在你的電腦上會是完整的檔案路徑),波浪線 ~ 和 ^ 標出出事的那一段。第 10 課會專門教怎麼讀這些訊息。
Traceback (most recent call last):
File "main.py", line 2, in <module>
total = price + 10
~~~~~~^~~~
TypeError: can only concatenate str (not "int") to str
「只能把字串(str)接上字串,不能接 int」。修正:要算數就先轉 int(price) + 10;要接成文字就寫 price + str(10)。Traceback (most recent call last):
File "main.py", line 1, in <module>
print(10 + "5")
~~~^~~~~
TypeError: unsupported operand type(s) for +: 'int' and 'str'
左邊是整數時,訊息變成「+ 不支援 int 和 str 這兩種運算元」。兩種訊息都在說同一件事:型別對不上。Traceback (most recent call last):
File "main.py", line 2, in <module>
cups = int(text)
ValueError: invalid literal for int() with base 10: '3.5'
「'3.5' 不是 int() 看得懂的十進位整數寫法」。型別沒錯(確實是字串),是值的內容不對,所以叫 ValueError。使用者可能打小數時,改用 float(text)。Traceback (most recent call last):
File "main.py", line 2, in <module>
print(n / 0)
~~^~~
ZeroDivisionError: division by zero
/、//、% 的右邊都不能是 0。cups = input() 之後寫 cups * 45,Python 不會出錯,而是安安靜靜地給你 45 個重複的文字。沒有錯誤訊息的錯最難找,看到奇怪的輸出時,先用 type() 印出型別確認。0.1 + 0.2 為什麼不是 0.3
電腦用二進位(只有 0 和 1)存數字。像 0.1 這樣的小數,換成二進位是無限循環的,只能存一個非常接近的值,所以浮點數存的是近似值。平常印出來看不到差異,但兩個近似值相加,誤差偶爾會露出來。
入門階段記住兩件事就夠了:要顯示給人看時,用 round(x, 2) 四捨五入到需要的位數(第 4 課的 f-string 也能控制小數位數);不要用 == 直接比較兩個浮點數是否相等。真的要處理金額,實務上會用整數存「分」或使用 decimal 模組,等學完基礎再看就好。
完整範例一:結帳程式(轉型、混合運算、印出結果)
# 晴空咖啡結帳:input() 拿到的一律是字串,這裡先用寫死的字串模擬
cups_text = "3" # 使用者打的「3」
price_text = "45.5" # 使用者打的「45.5」
cups = int(cups_text) # "3" → 3(整數 int)
price = float(price_text) # "45.5" → 45.5(浮點數 float)
total = cups * price # int 和 float 一起算,結果是 float
print(total) # 136.5
print(type(cups), type(price), type(total))
print("總共 " + str(total) + " 元") # 數字先用 str() 轉成文字,才能用 + 接起來
print("總共", total, "元") # 也可以交給 print:用逗號分開,它會自己轉成文字
136.5
<class 'int'> <class 'float'> <class 'float'>
總共 136.5 元
總共 136.5 元
最後兩行印出一樣的結果。用 + 串接時要自己處理型別和空格;用逗號交給 print 時,它會把每個值轉成文字、中間自動加一個空格。
完整範例二:整除、餘數與運算順序
# 135 分鐘是幾小時幾分?// 拿整除的部分,% 拿餘數
minutes = 135
hours = minutes // 60 # 135 裡面有幾個完整的 60 → 2
rest = minutes % 60 # 拿走 2 個 60 之後還剩多少 → 15
print(hours, "小時", rest, "分鐘") # 2 小時 15 分鐘
print(minutes / 60) # 2.25:/ 一律得到 float,會保留小數
# 運算順序:** 先算,再來 * / // %,最後 + -;有括號先算括號
print(2 + 3 * 4) # 14:先算 3 * 4
print((2 + 3) * 4) # 20:括號裡先算
print(2 * 3 ** 2) # 18:先算 3 ** 2 = 9
2 小時 15 分鐘
2.25
14
20
18
完整範例三:浮點數誤差
# 浮點數是用二進位「近似」小數,偶爾會差一點點
a = 0.1 + 0.2
print(a) # 0.30000000000000004
print(a == 0.3) # False:兩個近似值剛好不一樣
print(round(a, 2)) # 0.3:要顯示給人看時,四捨五入到需要的位數
0.30000000000000004
False
0.3
以後在哪裡會再遇到
讀 AI 或資料分析的範例程式時,型別問題會換個樣子出現。用 pandas 讀進 CSV 檔,如果某一欄的數字裡混了「無」或「1,200」這種寫法,整欄都會被當成文字,直接算平均就會出錯,得先轉成數字;NumPy 陣列也有自己的型別(dtype),整數陣列和浮點數陣列算出來的結果不一樣。這些都是同一個觀念:先看清楚資料是什麼型別,再決定能做什麼運算。
✅ 自我檢測
6 題都是小段程式,輸出都用 Python 3.13 實際跑過。選完會立即顯示對錯與解析,全部作答後會出現總分。目前得分:0 / 6