數字與文字
大部份的程式語言都有設計不同的資料型態,有簡單型態的也有複雜的集合型態,這個章節先來看看最常見的數字與文字。
數字
對一般人來說,數字就是數字,這是我們每 天眼睛張開就要面對的東西,再熟悉不過了。大部份的程式語言都有數字可以用,在 Python 的數字主要有分兩種,一個是沒有帶小數點的「整數(Integer)」,另一個則是帶有小數點的,在程式語言的世界通常會稱它做「浮點數(Float)」。
你可能會好奇,有沒有帶小數點不一樣都是數字嗎?是的,的確都是數字沒錯,但不要以為只差在有沒有小數點而已,事實上它們在電腦的世界裡是以不同的型態存在的,我們可以使用內建函數 type()
來試試看:
>>> type(1450)
<class 'int'>
>>> type(1450.0)
<class 'float'>
雖然現在大家可能還看不懂什麼是 class
,但大概可以把它解釋成 1450
「是一種」整數(int)以及 1450.0
「是一種」浮點數(float)的意思。關於整數跟浮點數的細節我們晚點再來看,先來看看大家小時候學過的四則運算:
四則運算
>>> 1 + 2
3
>>> 10 - 8
2
>>> 3 * 4
12
>>> 10 / 2
5.0
如果在這裡我還得解釋什麼是四則運算,未免也太侮辱大家的智商了。在計算過程中如果把整數跟浮點數混在一起算的話,計算出來的結果會自動轉變成浮點數:
>>> 1 + 2.0
3.0
>>> 10.0 - 8
2.0
>>> 3 * 4.0
12.0
就算計算的結果剛剛好是整數,得到的答案也是浮點數。另外,Python 使用除法算出來的結果,就算剛好整除,答案也是帶小數點的浮點數。如果你想要的是整數除法的話,在 Python 要使用兩個 /
:
>>> 10 // 2
5
>>> 10 // 3
3
但要注意用 //
算出來的答案不管有沒有整除,小數點部份都會直接被丟掉。我們以前學過的「先乘除、後加減,小括號先算」的規則也同樣適用在這裡:
>>> 1 + 2 * 3
7
>>> (1 + 2) * 3
9
那如果把數字跟... 例如文字或是其他資料型態混在一起算呢?像 JavaScript 就可以把數字 1
跟文字 "1"
放在一起變成 "11"
,還能把數字跟陣列加在一起。但,這真的是個好主意嗎?你可能不會知道這種在 JavaScript 的強迫轉型(Type Coercion)的設計造成了多少不必要的麻煩。所以在 Python 如果你幹這件事,你會很直接的收到 Python 給你的抱怨:
>>> 1 + "1"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
看到了嗎?Python 沒這麼好講話,數字跟字串是不能放 在一起做運算的。除了常見的四則運算外,還有幾個也算常用的數學運算,例如兩個星號 **
是幾次方的意思:
# 3 的 2 次方
>>> 3 ** 2
9
# 5 的 3 次方
>>> 5 ** 3
125
使用 %
符號可以取餘數:
>>> 8 % 3
2
>>> 8 % 4
0
不只這些符號,Python 有內建一些還不錯用的數學計算函數,例如用來做四捨五入的 round()
:
# 四捨五入到整數位
>>> round(3.1415926)
3
# 四捨五入到小數點以下第 2 位
>>> round(3.1415926, 2)
3.14
如果沒帶第二個參數的話,就是計算到整數位。這個 round()
函數會算出離這個數字最近的整數,例如 0.4999
就會得到 0
, 超過中間值一點點的 0.5001
就會得到 1
:
>>> round(0.4999)
0
>>> round(0.5001)
1
這四捨五入的概念我們小學都學過,沒什麼問題,但如果是剛好正中間的 0.5
呢?
>>> round(0.5)
0
咦?怎麼不是 1
?這好像跟我們以前學的四捨五入不太一樣!
有個叫做「電機電 子工程師學會(IEEE)」的單位,這個單位制定了許多工業界的標準,其中有一個編號 IEEE 754 號的標準定義了關於浮點數的表示法,也包括在計算浮點數的時候應該怎麼做捨入。
根據 IEEE 754 的規範,在做捨入計算的時候會計算出最接近的整數,但如果遇到中間值的時候,有兩種做法:
- 「ties to even」就是做捨入計算的時候,會選擇離這個數字最近的「偶數」。
- 「ties away from zero」跟上面不同,在做捨入計算的時候,會選擇離 0 比較遠的整數。
不同的程式語言的設計會有些不同,Python 選擇了第一種做法,這也是 IEEE 754 比較推薦的做法,而 Ruby 就是選第二種做法。我們先來看看第二種做法,什麼叫選擇「離 0 比較遠的整數」?我用 Ruby 舉個例子:
# 正數
>> (0.5).round
=> 1
>> (1.5).round
=> 2
# 負數
>> (-0.5).round
=> -1
>> (-1.5).round
=> -2
這比較接近我們平常講的「四捨五入」。而 Python 3 選擇了第一種做法,也就是選擇「比較近的偶數」:
# 正數
>>> round(0.5)
0
>>> round(1.5)
2
# 負數
>>> round(-0.5)
0
>>> round(-1.5)
-2
如果要給它個口訣的話,就是「四捨六入五成雙」,這種捨入法又稱「銀行家捨入法(Banker's Rounding)」。為什麼要這樣設計呢?這是因為這樣的設計可以減少四捨五入的時候造成的數字分佈偏差。什麼偏差?難道四捨五入不公平嗎?想想看,假設我有一顆九面骰子,上面分別刻了 1 到 9 的數字,如果丟出 1、2、3、4 算你贏,丟出 5、6、7、8、9 算我贏,這樣你覺得這樣公平嗎?
但為什麼我在上面特別提到 Python 3?這是因為在 Python 2 的 round()
是選擇第二種做法,就是我們小時候學的四捨五入!這也是 Python 2 跟 Python 3 不相容的原因之一。
另外,在 Python 的官方文件中有特別舉了一個例子:
# 你覺得答案是什麼?
>>> round(2.675, 2)
就我們前面學到的,應該會是 2.68
吧?但答案是卻是 2.67
,這是因為在 IEEE 754 的規範中,浮點數的表示方式是有誤差的,其實我們肉眼看到的 2.675
並不是剛好在 2.67
跟 2.68
的正中間,而是比較偏向 2.67
一點點,所以答案算出來是 2.67
。關於浮點數的誤差待會就會知道是怎麼回事。
除了內建的 round()
之外,在 Python 有個專門放數學計算相關的 math
模組,裡面有無條件進位以及無條件捨去等函數。在 Python 要使用的時候,需要使用 import
語法明確的引入這個模組才能使用:
# 匯入 math 模組
>>> import math
# 圓周率
>>> math.pi
3.141592653589793
# 無條件進位
>>> math.ceil(3.14)
4
# 無條件捨去
>>> math.floor(3.14)
3
補充一個不太重要的冷知識,Ceil 的英文是「天花板」,而 Floor 是「地板」的意思。math.ceil()
跟 math.floor()
這兩個函數做的事情就是就是把數字往天花板跟地板方向推,往天花板推的就會變成「無條件進位」,而往地板推就是「無條件捨去」。
還記得在學生時期讓人很頭痛、學了也不知道以後要幹嘛的三角函數跟對數嗎?在 Python 也有:
# 三角函數
>>> math.sin(math.pi / 2)
1.0
>>> math.cos(math.pi)
-1.0
# 取 2 的對數
>>> math.log(8, 2)
3.0
更多關於 Python 的數學模組功能,可參閱官方文件說明。
Python 數學模組 https://docs.python.org/library/math.html
關於數字的最大值或最小值,有些程式語言在宣告整數或浮點數的時候,會根據不同型態而有不同的上下限,例如最大可能像是 2 的 64 次方之類的數字。畢竟電腦的記憶體有限,所以在 Python 的數字也不可能無限位數,只是上限還滿大的。以目前的 Python 版本的設定,最高可以有 4,300 位數,當然這用來算圓周率還是不夠用,但對一般的運算應該是相當夠用了。也就是說,如果我們故意挑戰 Python 的極限,可能會看到類似這樣的錯誤:
# 故意印出 10 的 4500 次方!
>>> 10 ** 4500
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Exceeds the limit (4300 digits) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit
從錯誤訊息看的出來已經超過上限了,但如果想要提高額度,還是可以透過修改設定做到這件事,只是這就不是我們現在這種等級該煩惱的事。
型別轉換
雖然在 Python 的數字有整數跟浮點數之分,但彼此之間是可以透過內建的 int()
以及 float()
進行轉換的,例如:
# 整數
>>> age = 18
# 轉換成浮點數
>>> float(age)
18.0
# 浮點數
>>> pi = 3.14
# 轉換成整數
>>> int(pi)
3
a = a + 1?
如果你是數學系的學生,你看到 a = a + 1
這樣的數學式,大概會覺得怎麼可能會有哪個值等於自己加 1 !當然以數學來說是不可能發生,但對 Python 以及目前大部份的程式語言來說,一個等號不是「等於」的意思,而是「指定(Assign)」的意思,a = a + 1
會先處理等號右邊的運算,把原本的變數 a
的值加 1 之後再指定給等號左邊變數 a
,例如:
# 原本 18 歲
>>> age = 18
>>> age = age + 1
# 現在老一歲,變 19 歲了
>>> age
19
因為這種 a = a + 1
的寫法很常用,所以也有另一種更短的寫法:
age += 1
把加號移到等號的左邊,寫成 +=
,這樣跟原本的效果是一樣的。看到這裡,聰明如你一定不只能舉一反三,還能舉一反五,以下這五行:
a -= 2
b *= 3
c /= 4
d **= 3
e //= 3
就等於以下這五行的效果:
a = a - 2
b = b * 3
c = c / 4
d = d ** 3
e = e // 3
另外,如果是 a += 1
這種一次只增加 1 的話,有些程式語言有 a++
或 ++a
這種更短的寫法,不過 Python 沒有這樣的設計。
科學記號表示法
我記得在我讀高中的時候,老師有時候會把一些特別大或是特別小數字用另一種方式來表示,例如在我高中化學曾經學過的亞佛加厥常數 6.02 × 1023 或是原子質量 1.66 × 10-27,老實說當時我不知道學這個常數或是原子質量要幹嘛,只知道用這種寫法可以讓數字看起來簡單一點,這樣的表示法稱之「科學記號表示法(Scientific Notation)」。使用科學計算表示法除了可以簡化原本很大或很小的數字外,在做運算的時候也挺方便,例如 30,000,000,000 乘以 0.000000015 等於多少?我相信這不難算,但那麼多個零看了眼睛都花了,如果改寫成科學記號表示法的話會變成 3 x 1010 乘以 1.5 x 10-8,這樣一來計算的時候就可以分開算,前面 3 x 1.5 = 4.5,而後面的 1010 x 10-8 就會得到 102,最後答案就是 4.5 x 102,也就是 450。
我們日常生活最常見的數字系統應該就是十進位了,我 們每天能去超商買午餐付紙鈔會找零錢這件事就是十進位,剛剛講到的科學記號表示法 4.5 x 102 也是建立在十進位的系統之上。在 Python 中,科學記號表示法的寫法是用 e
來表示 10 的次方,例如 1.23 x 104,可以寫成:
>>> 1.23e4
12300.0
除了十進位外,常見的還有用在時間上的還有 24 進位以及 60 進位,而電腦主要使用二進位。接著我們來看看不同進位之間要怎麼進行轉換,例如十進位的數字 7.625 要怎麼轉成二進位?整數的部份比較簡單,整數 7 可以分解成:
1 x 22 + 1 x 21 + 1 x 20 = 4 + 2 + 1 = 7
所以 7 轉成二進位就是 111
。小數 .625 的部份也是差不多的原理,只是指數要改用負數:
1 x 2-1 + 0 x 2-2 + 1 x 2-3 = 0.5 + 0 + 0.125 = 0.625
所以 7.625 轉成二進位就是 111.101
。如果再用科學記號表示法就會變成 1.11101 x 22。7.625 一個是剛好可以完美轉換成二進位的數字,但不是每個數字都能這麼剛好轉換成二進位,如果再大一點點或小一點點,例如 7.626 呢?整數部份沒問題,還是 111
,但小數部份就麻煩了,這有點難算,如果一直算下去你會得到一個超級長的結果 0.10100000010000011000100100110111010010111100011010101
。事實上這根本算不完,就跟 10 除以 3 會得到 0.333333333... 一樣的無限循環,你在畫面上看到的只是一小部份。所以 7.626 轉換成二進位就變成 111.10100000010000011000100110...
,轉換成科學記號表示法就會變成 1.1110100000010000011000100110... x 22,這看起來還是差不多囉嗦,沒什麼幫助。很多程式語言都是根據 IEEE 754 的規範來設計浮點數,IEEE 754 規範了幾種用來呈現浮點數的方式,其中 32 位元的就是「單精準度」,而 64 位元因為是 32 位元的兩倍,所以就是「雙精準度」。就以 32 位元的單精確度的遊戲規則來說:
第 1 位元是放正負數的符號(sign bit),0 表示正數,1 表示負數。 第 2 ~ 9 這 8 個位元是指數(exponent) 剩下第 10 ~ 32 這 23 個位元則是放實際的值(fraction)
也就是說,一個 32 位元的浮點數,只能存放 23 位有效數值。如果是雙精準度的 64 位元的話,它的指數部份佔 11 位元,所以實際能存放的有效位數只有 52 位數。
但問題是,後面會無限循環的數字就算是能放 1000 位數也沒用,再多位數就是不夠放。沒辦法顯示完整數字怎麼辦?這也沒辦法了,就只能算了吧。對,就是算了,就是因為這樣,所以常會說浮點數不是 100% 精準的原因。
正因為浮點數不是 100% 精準,所以在運算上也會有一些問題,例如當我們計算 0.1 + 0.2 的時候...
0.1 + 0.2 等於多少?
你也許會好奇,這種小學生的問題有什麼好問的,0.1 加 0.2 就是 0.3 啊,不然呢?其實這是個有趣的面試題,以人類的常識來說, 0.1 + 0.2 就是 0.3,但以電腦來說就不是這樣了。如前面所說,電腦裡存放的 0.1 跟 0.2 都不是剛好真的 0.1 跟 0.2,只是非常接近而已。所以在電腦上運算 0.1 + 0.2 的結果也會很接近 0.3,因為有效位數沒辦法存放所有的位數,剛好在相加進位之後變成 0.30000000000000004
,所以你打開 Python 的 REPL 試一下就會知道:
>>> 0.1 + 0.2
0.30000000000000004
>>> 0.1 + 0.2 == 0.3
False
之前大家常會拿這個出來笑 JavaScript 是個爛程式設計語言,事實上只要浮點數是照 IEEE 754 標準實作的,像 Python 跟 Ruby 都是,印出來的答案都不會剛好等於 0.3。所以不是程式語言設計爛,而是浮點數本身就是這樣設計的,大家都只是照著規範做事而已。
位元運算
剛有稍微提到要怎麼把我們日常生活會用到的十進位數字轉換 成二進位數字,例如十進位的 25 轉成二進位就是 11001,Python 有個內建的 bin()
函數可以把整數換成成二進位表示法:
>>> bin(25)
'0b11001'
前面的 0b
是 Python 的表示法,表示這是一個二進位的數字,這樣我們就不用自己算了。相對的,如果要把二進位數字換成十進位數字,可以用內建的 int()
函數:
# 第二個參數表示是二進位
>>> int("11001", 2)
25
# 預設是十進位
>>> int("100")
100
在二進位的世界裡有一種數字的運算方式叫做「位元移位(Bitwise Shift)」,例如把數字 25 的二進位 11001
整個「向右移」一個位數,就會變成 1100
,最右邊的 1 會被擠掉。經過右移一位的結果再換算回十進位就會變成 12;同理,如果向右一次移動兩個位數,原本的 11001
就會變成 110
,換算回十進位就會變成 6。
相對的,如果是「向左移」,就會在右邊補 0,例如 11001
向左移一位就會變成 110010
,換算回十進位就會得到 50;如果是向左移兩位 110010
,換算回十進位就會得到 100。
在 Python 可以使用 >>
或 <<
來做位 元移位的計算:
# 向右移一位
>>> 25 >> 1
12
# 向右移兩位
>>> 25 >> 2
6
# 向左移一位
>>> 25 << 1
50
# 向左移兩位
>>> 25 << 2
100
有發現什麼有趣的地方嗎?位元移位其實就是在做乘法跟除法,往右移一個位置就是除以 2,往右移兩次就是除以 2 再除以 2;同理,向左邊移一位數就是乘以 2。
不是數字?
講到 IEEE 754,裡面有記載一個特別的值叫做「NaN」,它是「Not A Number」的縮寫,從字面上大概能猜出來它「不是數字」。但其實它是個數字,只是它用來表示一些不合理或沒意義的數學運算,例如無限大減無限大。有些人會覺得有點怪,明明就說不是數字,但竟然是個數字?這就像看到一個人舉著牌子說「這裡沒有人」,但這個人就站在你面前是一樣的概念,總得有個人舉著牌子才能說這裡沒有人,所以 IEEE 754 才設計出 NaN 這個特別的數字。
NaN 在 Python 的世界裡是一個浮點數,它有一些比較特別的特性。我們可以透過 float()
函數或是內建的 math
模組來產生一個 NaN:
import math
nan1 = float("nan")
print(nan1) # 印出 nan
print(type(nan1)) # 印出 <class 'float'>
nan2 = math.nan
print(nan2) # 印出 nan
print(type(nan2)) # 印出 <class 'float'>
NaN 就像黑洞一樣,大部份的數字運算遇到它都會變成 NaN,例如:
nn = float("nan")
print(nn + 1) # nan
print(nn - 20) # nan
print(nn * 100) # nan
print(nn / 100) # nan
print(nn % 2) # nan
雖然 NaN 很特別,但它就是一個數字,所以它也有一些數學運算的特性,例如:
# 任何數字的 0 次方都是 1
print(nn**0) # 1.0
# 1 的任意次方都是 1
print(1**nn) # 1.0
在 Python 所有的值都會等於自己,例如 1 == 1
,這聽起來很像廢話,但 NaN
的特殊設計之一,就是它跟任何值都不會相等,包括它自己:
print(nn == 123) # False
# 它瘋起來連自己都不認得!
print(nn == nn) # False
所以千萬不要拿它去跟任何值比較,答案永遠都是 False
。如果想要判斷某個值是不是 NaN,應該使用 math
模組裡的 isnan()
函數:
>>> import math
>>> math.isnan(123)
False
>>> nn = float('nan')
>>> math.isnan(nn)
True
無限大?
另一個同樣也是記載在 IEEE 754 裡的特殊值叫做「無限大(Infinity)」。是的,無限大不只是個概念,它也是一個值。Python 按照 IEEE 754 的設計,無限大是一個浮點數,當某個浮點數超過它所能表示的範圍時,就會變成無限大。我們可先看一下 Python 裡關於浮點數的相關資訊:
>>> import sys
>>> sys.float_info
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, ... 略 ...)
這裡的 import sys
就是匯入 sys
模組,這語法可先不管它,從上面顯示的資訊大概可以猜的出來浮點數的最大值 max
是 1.7976931348623157e+308
,也就是說如果浮點數超過最大值就會變成無限大,例如:
>>> 1e308
1e+308
>>> 1e309
inf
如果要直接產生一個無限大的值,可以使用 float()
函數搭配 inf
或 -inf
字串,或是使用 math
模組裡的 inf
定義:
import math
# 正無限大
p_inf1 = float('inf')
print(type(p_inf1)) # 印出 <class 'float'>
p_inf2 = math.inf
print(type(p_inf2)) # 印出 <class 'float'>
# 負無限大
n_inf1 = float('-inf')
print(type(n_inf1)) # 印出 <class 'float'>
n_inf2 = -math.inf
print(type(n_inf2)) # 印出 <class 'float'>
這裡其實要用 float('Infinity')
也行,只是用 "inf"
比較短一點。如果要拿任何數值跟無限大進行比較,任何數值跟它比都比它小,相對的,任何數值跟負無限大比都比它大:
p_inf = float("inf")
n_inf = float("-inf")
print(123 < p_inf) # True
print(123 > n_inf) # True
print(p_inf > n_inf) # True
這看起來很合理。無限大一樣可以進行數學運算,有些還算容易想像,例如:
p_inf = float("inf")
n_inf = float("-inf")
# 無限大的 100 萬倍還是無限大
print(p_inf * 1000000) # inf
# 無限大加上或乘以無限大還是無限大
print(p_inf + p_inf) # inf
print(p_inf * p_inf) # inf
# 無限大的無限大次方!
print(p_inf**p_inf) # inf
有一些比較特別的操作但也還能理解,例如:
p_inf = float("inf")
n_inf = float("-inf")
nan = float("nan")
print(p_inf**0) # 1.0,任何數字的 0 次方都是 1
print(1**p_inf) # 1.0,1 的任意次方都是 1
print(p_inf - n_inf) # inf,無限大減掉負無限大是無限大
print(p_inf - p_inf) # nan,無限大減掉無限大沒有定義
print(p_inf + n_inf) # nan,負無限大加上無限大沒有定義
print(p_inf + nan) # nan,任何數跟 NaN 進行運算都是 NaN
最後,跟 NaN 一樣,如果要判斷某個值是不是無限大,可以使用 math
模組裡的 isinf()
函數:
import math
p_inf = float("inf")
n_inf = float("-inf")
print(math.isinf(p_inf)) # True
print(math.isinf(n_inf)) # True
對我來說,無限大是個很酷的概念,但因為我的工作或專案幾乎都是跟網站有關,在我過往二十幾年的工作生涯裡我好像沒什麼機會在工作上用到這麼酷的東西就是了。
文字
除了數字之外,在大部份的程式語言裡最常用的資料型態就是文字了。不過「文字(Text)」是一般人在講的,在工程師的程式世界裡通常會叫它「字串(String)」,用來表示一連「串」的文「字」。在 Python 裡的字串會使用成對的引號把它包起來,例如:
print('hello world')
print("你好")
你想用單引號或雙引號都可以,在其他程式語言的單引號跟雙引號可能會有功能上的差別,但在 Python 這兩種引號並沒有什麼差別,想用哪種都行。Python 官方的 PEP(Python Enhancement Proposals)文件有提到:
In Python, single-quoted strings and double-quoted strings are the same. This PEP does not make a recommendation for this. Pick a rule and stick to it.
想要用單引號或雙引號都好,只要選一個規則然後堅持用下去就好。雖然單引號或雙引號沒什麼差別,但如果混著用會出問題:
print('hello world") # 語法錯誤
print("你好') # 這樣也不行
像上面這樣寫會造成語法錯誤,字串需要用成對的單引號或雙引號包起來才行。在單引號裡可以包雙引號,在雙引號裡也可以包單引號,例如:
print("Hi, I'm Kitty") # 印出 Hi, I'm Kitty
print('He said "Hello World"') # 印出 He said "Hello World"
如果要在單引號裡再放一個單引號,或是在雙引號裡再放一個雙引號,因為程式無法判斷到底這是一般文字裡的引號還是要用來包字串的引號,我們可以用個特別的符號來做個標記:
print('Hi, I\'m Kitty') # 印出 Hi, I'm Kitty
這個 \
符號就是告訴 Python 說「它就只是個一般的引號而已,不是給你當作字串結束用的」。這個 \
符號又稱「跳脫字元(Escape Character)」。除了剛才的用途外,在 \
後面加上一些字還有特別的效果,例如 \n
是換行的意思,\t
是 Tab 的意思:
>>> print("hi, \n 我們不同行")
hi,
我們不同行
>>> print("hi, \t 這裡會跳一大格")
hi, 這裡會跳一大格
既然 \
符號可以用來「跳脫」字元,但如果我們真的需要 \
這個字,例如想要印出 C:\Windows
這樣的字串怎麼辦?跟跳脫單引號、雙引號的概念一樣,你也可以多加一個跳脫符號,來跳脫 \
這個跳脫符號:
>>> print("C:\\Windows")
C:\Windows
這樣就行了 :)
多行文字
在 Python 使用單引號或雙引號包起來字串是不能換行的,像這樣:
message = "Hello
Kitty" # 語法錯誤
print(message)
這樣寫會造成語法解析錯誤而無法執行。如果你真的想在字串裡加入換行的話,可以使用剛剛學到的 \n
。Python 有提供一個特別的字串寫法,可以讓你在字串裡直接換行,就是用 3 個成對的單引號或雙引號:
message = """
Hello
Kitty
"""
print(message)
前面我們曾經學過 Python 使用 #
符號來做為註解,不過一個 #
符號的作用範圍只有一行,如果想要多行註解也很簡單,就是每一行都加 #
。這聽起來好像有點麻煩,但在大部份的編輯器(例如 VS Code)只要按下 CMD
+ /
(在 Windows 則是 Ctrl
+ /
)就可以快速的切換註解的開關,所以其實也沒多麻煩。
也許你會在其他的教學資料裡看到利用三個引號可以做多行註解的效果,像這樣:
print("Hello")
"""
這是一行註解
這是第二行註解
這是第三行註解
"""
print("World")
但這裡我得特別跟各位說,三個引號的寫法並不是註解,它就只是可以換行的多行文字而已。因為這個多行文 字我們並沒有指定變數給它,就像是船過水無痕的概念,執行完之後這段文字就消失了,不會影響執行結果,所以有時候在一些 Python 的原始碼裡面會看到用這種方式來撰寫文件或是測試。
再跟大家說個不重要的冷知識,Python 的編譯器在執行上面這幾行程式的時候,由於中間的多行文字並沒有指定給任何變數,在編譯的過程就會直接被拿掉了,如果用更專業的說法,就是這些東西根本不會被編譯到 Bytecode 裡。
轉換型別
前面提到的 int()
或 float()
可進行整數及浮點數型態的轉換,而 Python 內建的 str()
函數可以把其他型別轉成字串:
>>> str(18)
'18'
>>> str(True)
'True'
>>> str([])
'[]'