從 JavaScript 角度學 Python(4) - 型別與變數

前言

oh!終於要開始學習寫 Python 了呢!(被揍),都混了三天,我如果再不開始寫 Python 的話,我想應該一推人準備退訂閱了,但是在開始學習之前,我們會先從最基礎的型別開始學習,那麼這邊也會盡可能使用 JavaScript 兩者語法上的差異去做比較與學習唷。

型別

一開始我們先來簡單了解一下關於 Python 型別的部分…

你良心不痛嗎!!

哎,別這樣說,雖然我很想再多偷懶個幾篇,但是我想是差不多開始認識 Python 怎麼寫,但是要開始寫之前總要先學基礎對吧?

所以在前面我們先快速複習一下 JavaScript 中有哪些原始型別:

  • String - 字串
    • '這是一個字串'
    • "這也是一個字串"
  • Boolean - 布林
    • true
    • false
  • Number - 數字
    • 100000
    • 3.141592653
  • Undefined - 未定義
  • Null - 空值

以及後來新增的:

  • Bigint - 整數數值
    • 9007199254740991n
  • Symbol - Symbol

這些之外的我們通通稱之為物件型別,所以通常會看到人家講原始型別與物件型別。

如果你對於 JavaScript 的型別觀念還不是那麼熟悉的話,那麼我建議你可以閱讀我先前寫的「JavaScript 核心觀念(14)-運算子、型別與文法-原始型別及物件型別」文章會有更詳細的說明唷!

那麼 Python 呢?Python 的型別主要區分為三大類:

  • 數值型別
  • 字串型別
  • 容器型別

很特別吧?竟然直接區分成三種型別,尤其是容器型別更是特別。

一開始我們先來聊聊比較接近 JavaScript 型別的「數值型別」與「字串型別」,而容器型別我們在別的章節再來聊吧!

不可否認 Python 與 JavaScript 在型別定義上確實是比較不一樣,所以就讓我們先來看看「數值型別」與「字串型別」,雖然是講數值型別與字串型別,但是實際上這兩個型別底下還會再細分相關的型別:

  • 數值型別
    • int - 整數
    • floats - 浮點數
    • boolean - 布林
  • 字串型別
    • string - 就是字串你還想怎樣?

今天很嗆哦

(前面開玩笑的。)

字串型別與 JavaScript String 型別並沒有任何差異,但是我們可以看到最明顯的差異是在於「數值型別」,在 JavaScript 中不論是 var num = 1.23456; 或者是 var num2 = 123;,我們都是通通歸類為 Number 型別,當然我們也可以驗證一下:

1
2
3
4
var num = 1.23456;
var num2 = 123;
console.log('Number', typeof(num)); // Number number
console.log('Number', typeof(num2)); // Number number

只是在 Python 中卻有區分出 int 型別與 floats 型別,這兩者型別如何辨識呢?只需要看它有沒有小數點就對了。

若有小數點的話就是浮點數,所以 var num = 1.23456; 在 Python 中其實是浮點數(floats),而 var num2 = 123; 則是整數(int)。

那…JavaScript 中的 UndefinedNull 呢?Python 也存在嗎?

Undefined 就不說了,畢竟這是 JavaScript 的特殊型別,只要你有在變數宣告之前呼叫過變數的話,一定很常看到 Undefined (這部分又牽扯到提升就不提了。):

1
2
console.log(myName); // undefined
var myName = 'Ray';

但是 Null 這個型別也不存在於 Python 中,所以如果你若輸入以下語法是會出現錯誤的,那這邊我們就來簡單寫一點點的 Python 來驗證看看:

(注意,Python 不用加上結尾分號)

1
hello = Null # name 'Null' is not defined

取而代之的是 Python 所使用的是 None,這邊要注意 None 顯示出來會是一個 Nonetype:

1
2
hello = None
type(hello) # <class 'NoneType'>

(type 的語法與 JavaScript 的 typeof 相同,主要是查看型別用。)

所以可以把 JavaScript 的 Null 想像成是 Python 的 None

除此之外 <class 'NoneType'> 這一段的意思是在講這個變數是 NoneType 類型,如果是一個字串的話,就會是 <class 'str'> 也就是字串類型概念,而 None 這也是屬於 Python 的特殊型別。

題外話一下在 Python 2.x 則是顯示 <type 'str'>,只是在 Python 3.x 改成了 <class 'str'> 而已,所以不論是 <class 'str'> 還是 <type 'str'> 都是代表著當前變數是什麼型別的意思。

變數

變數可以說是所有程式語言最基礎最重要的起手式,因為我們會很常需要使用變數儲存資料,如果以 JavaScript 作為舉例就是儲存 AJAX 回來的資料最為常見。

這邊以 JavaScript 作為起手式,當我們在建立變數時,通常都會使用 var 或者 ES6 語法 letconst,以下這邊就先以 var 作為舉例:

1
2
3
4
5
6
7
8
9
var myNameTest = 'Ray';
var numTest = 1;
var num2Test = 3.14
var boolTest = true;

console.log('String', typeof(myNameTest)); // String string
console.log('Number', typeof(numTest)); // Number number
console.log('Number', typeof(num2Test)); // Number number
console.log('Boolean', typeof(boolTest)); // Boolean boolean

Python 在宣告變數上與 JavaScript 是有一點點的不同,在 Python 中我們可以不使用任何的變數宣告關鍵字 (varlet or const) 來宣告變數,只需要直接撰寫變數名稱並賦予值或結果就可以了。

底下這邊就以上方示範的 JavaScript 範例直接改寫成 Python 結構:

1
2
3
4
myNameTest = 'Ray'
numTest = 1
num2Test = 3.14
boolTest = True

這邊你應該會注意到 Python 的 Boolean 是採用首字大寫的方式撰寫,這個與 JavaScript Boolean 全小寫完全不同,這是一個小細節要注意一下:

1
2
boolTest = True
boolTest = False

通常我們在撰寫 JavaScript 的時候,我們可以使用 console.log 輸出結果,而 Python 則是使用 print() 函式輸出結果:

1
2
3
4
5
6
7
8
9
myNameTest = 'Ray'
numTest = 1
num2Test = 3.14
boolTest = True

print('String', type(myNameTest))
print('Number', type(numTest))
print('Float', type(num2Test))
print('Boolean', type(boolTest))

(題外話一下 console.xxx 還有很多種,例如:console.dirconsole.table 等等,如果你不熟悉的話,可以閱讀我這一篇筆記 「淺談 JavaScript 中的 Debug 神器 Console」 了解一下。)

最後讓我們稍微透過一張圖一起比較一下兩者語法差異:

比較

將兩種程式語言放在一起之後應該會有人覺得 Python 的語法確實簡潔相當多,可能會萌生我該學 JavaScript 還是 Python 的錯覺,那我就會這樣給你一張圖:

從 JavaScript 角度學 Python

重新賦值

接下來我們來聊聊 重新賦值 這個行為,在 JavaScript 中會依據你的宣告方式的不同,而決定你這個變數是否可以被 再次重新賦值,因此讓我們看一下 JavaScript 宣告範例:

1
2
3
4
5
6
var myName = 'Ray';
myName = 'Ray'; // 可以被重新賦值
let sayHi = 'Hello Ray';
sayHi = 'Ray Hello'; // 可以被重新賦值
const isRay = 'not Array';
isRay = 'is Array'; // 無法被重新賦值

var 與 ES6 語法又有些許不同,因此這邊不著墨在 JavaScript 宣告變數上,若想再深入了解可以閱讀我先前寫「淺談 var 與 let 的差異以及有無宣告變數的差異」這一篇。

回到宣告變數的部分,使用 let 宣告的變數,若再一次使用 let 關鍵字重新宣告變數,是會出現錯誤的:

1
2
let myName;
let myName; // Uncaught SyntaxError: redeclaration of let myName

除此之外 JavaScript 的變數宣告又會因為宣告方式的不同而有作用域以及提升的問題,已經頭暈了嗎?不用擔心,這邊不會繼續著墨 JavaScript 的部分。

那麼 Python 呢?Python 會有這個問題嗎?

讓我們繼續看下去

接下來的觀念可能會與你在學 JavaScript 的觀念有一點衝突,主要原因是出在我們前面有講過 Python 在宣告變數時,是不用使用關鍵字來宣告的,因此就算你這樣子寫,也不會出現錯誤:

1
2
3
4
myNameTest = 'Ray'
print(myNameTest) # 'Ray'
myNameTest = 123
print(myNameTest) # 123

為什麼會這樣呢?對於 Python 來講 你並沒有重新宣告變數,而是告訴變數重新指向到新的值而已,這也就是為什麼並不會出現錯誤的原因,所以你也可以把它想像成 Python 是使用了 let 作為宣告,為什麼這樣說呢?因為如果你在變數宣告之前就先呼叫了這個變數是會出現錯誤的:

1
2
3
4
5
print(myNameTest) # NameError: name 'myNameTest' is not defined
myNameTest = 'Ray'
print(myNameTest)
myNameTest = 123
print(myNameTest)

概念是不是很很像 letconst 的暫時性死區概念呢(若不清楚暫時性死區可詳見 此篇 筆記)?這就是為什麼我會說可以把它想像成 let 了。那你可能會問說 Python 會有 Hoisting 嗎?我想是沒有的。

畢竟提升 (Hoisting) 這個行為是 JavaScript 獨特的運作模式。

最後是關於作用域的部分,關於作用域我打算下一次再來分享,看到現在的你有沒有感覺到 JavaScript 與 Python 各自美好之處呢?

混亂

執行 Python

接下來相信會有人疑惑該如何輸入上面這些程式碼,基本上有兩種方式

第一種是打開終端機,然後輸入 python 就會進入 Python 編譯器,概念就跟我們在終端機輸入 node 一樣:

Python 輸入模式

(上圖出現 Python 2.7 可忽略)

這邊退出終端機模式可以輸入 exit()quit() 等指令退出,或者是依據作業系統的組合按鈕來退出 Python 模式:

  • Window
    • CTRL + D
  • Mac
    • Control + D

第二種方式則是透過編輯器,這邊我是使用 VSCode 建立一個檔案叫做 ch1.py,然後貼入下方內容:

1
2
3
4
5
6
# 字串 string
myName = 'Ray'
blogUrl = 'https://hsiangfeng.github.io/'
# 輸出
print('字串 string', myName) # 字串 string Ray
print('字串 string', blogUrl) # 字串 string https://hsiangfeng.github.io/

接下來透過 VSCode 直接執行 .py 就可以看到結果囉

在終端機執行 Python 檔案

作者的話

因為自己滿喜歡吃台酒的花雕雞泡麵,所以異想天開的買了維力雞汁風味手打麵以及一罐花雕雞酒,沒想到維力雞汁風味手打麵和花雕雞酒加在一起後異常的香跟好吃,重點是花雕香可以自己決定。

關於兔兔們

兔法無邊

Liker 讚賞 (拍手)

如果這一篇筆記文章對你有幫助,希望可以求點支持或 牡蠣 鼓勵 (ノД`)・゜・。

Liker 是一個按讚(拍手)的讚賞機制,每一篇文章最多可以按五下(拍手),按讚過程你是完全不用付費的(除非你想要每個月贊助我 :D),你只需要登入帳號就可以開始按讚。
而 Liker 會依據按讚數量分配獎金給創作者,所以如果你願意按個讚我會非常感謝你唷。

Google AD

撰寫一篇文章其實真的很花時間,如果你願意「關閉 Adblock (廣告阻擋器)」來支持我的話,我會非常感謝你 ヽ(・∀・)ノ