Home
探索 Uedu
學生控制台
註冊會員/登入
研究知情同意中心
教師控制台
課程設定
支援與訊息
Uptime 數據

UeduGPTs

--

Jupyters

4

UG26 CISOSE26
臺北 AQI 46 · 臺中 AQI 28 · 臺南 AQI 24 · 高雄 AQI 33

AI 回覆桌面通知

AI 助教回覆完成時顯示桌面通知

聊天訊息通知

同學在討論區發送訊息時通知

聲音通知

每當有新通知時播放提示音

Python 入門與環境

Python 入門與環境:從第一支程式到直譯器原理

從一句問候出發,理解為何 Python 成為資料科學與 AI 的主力語言,並掌握直譯器、REPL、縮排語法與「變數即名牌」的核心直覺。

從一句問候開始:你的第一支 Python 程式

想像你坐在電腦前,想做一件很小的事:讓電腦對你說「哈囉」。在許多語言裡,這件事要先宣告型別、寫一個 main 函式、用大括號包住程式區塊,最後還得編譯。而在 Python 裡,你只需要打一行字:

print("哈囉,世界!")

按下執行,螢幕就回你:

哈囉,世界!

沒有樣板、沒有編譯指令、沒有分號。這種「想到什麼就寫什麼」的直接感,正是 Python 成為資料科學與人工智慧(AI)主力語言的起點。這篇文章會帶你從零認識 Python 的環境與語法直覺,並動手寫出能跑的程式。準備好你的鍵盤,我們開始。

Python 入門與環境概念示意圖

為什麼選 Python

語言這麼多,為什麼初學程式、做研究、進產業,大家都先學 Python?三個理由值得你記住。

第一,可讀性。 Python 的設計哲學寫在它的彩蛋裡,你可以親自執行:

import this

它會印出《The Zen of Python》,其中最重要的兩句是「Readable counts.(可讀性很重要)」與「There should be one obvious way to do it.(應該有一種顯而易見的做法)」。Python 強制用縮排來表達程式結構,逼著每個人寫出排版一致的程式碼。你讀別人的 Python,往往像讀英文句子。

第二,生態系(ecosystem)。 Python 之所以強,不只是語言本身,而是它背後龐大的套件(package)生態。做數值運算有 NumPy、做資料分析有 pandas、畫圖有 Matplotlib、機器學習有 scikit-learn、深度學習有 PyTorch 與 TensorFlow。這些工具已經被全世界的研究者與工程師打磨多年,你站在巨人的肩膀上。

# 一行安裝,全世界的數值運算工具就到手
# 在終端機(不是 Python 裡)執行:
# pip install numpy
import numpy as np
data = np.array([1, 2, 3, 4, 5])
print(data.mean())
# 輸出:3.0

第三,它是資料科學與 AI 的主力語言。 從學術論文的實驗程式、Kaggle 競賽,到 OpenAI、Google 的模型訓練流程,Python 幾乎是預設語言。學會它,等於拿到進入這個領域的通行證。

當然 Python 不是萬靈丹——它執行速度比 C 或 Rust 慢(後面深入段會解釋為什麼),不適合寫對效能極度敏感的底層系統。但對於「快速把想法變成可運作的程式」這件事,很少有語言比它更稱手。

直譯器與 REPL:跟電腦對話

要理解 Python 怎麼運作,先認識「直譯器(interpreter)」這個角色。

你寫的 Python 程式碼是給人看的文字。電腦看不懂,它只懂機器碼。中間需要一個翻譯官,把你的程式碼一行一行讀進來、翻譯、執行——這個翻譯官就是 Python 直譯器。最常見的實作叫 CPython,是用 C 語言寫成的(深入段會細談)。

直譯器最迷人的用法是 REPL,全名 Read-Eval-Print Loop(讀取-求值-印出-循環)。在終端機輸入 python 就會進入:

>>> 3 + 4
7
>>> name = "同學"
>>> "哈囉," + name
'哈囉,同學'
>>> len("Python")
6

每打一行,直譯器立刻讀取你的輸入、求值印出結果,然後等你下一行。這就像跟電腦即時對話。當你不確定某個語法怎麼用、想驗證一個小想法時,REPL 是最快的實驗場。鼓勵你現在就打開它玩玩看。

小提醒:REPL 裡的 >>> 是提示符號,是直譯器印給你的,你不需要自己打。

縮排即語法:空白有意義

如果你學過 C、Java 或 JavaScript,會習慣用大括號 { } 來框出程式區塊。Python 把這套全部拿掉,改用縮排來表達「誰屬於誰」。

score = 85
if score >= 60:
    print("及格")
    print("恭喜")
print("評分結束")

注意 if 底下那兩行 print 各往右縮了四格空白,它們屬於 if 的區塊;而最後一行 print("評分結束") 沒有縮排,所以無論及不及格都會執行。輸出是:

及格
恭喜
評分結束

縮排在 Python 裡不是排版美觀,而是語法本身。縮排錯了,程式就跑不動,或行為完全不同。看看這個對比:

# 反模式:縮排不一致會直接報錯
if score >= 60:
    print("及格")
      print("恭喜")   # 多縮了兩格 → IndentationError

慣例上,Python 社群的風格規範 PEP 8 建議用四個空白鍵縮排,不要用 Tab,而且全檔統一。大多數編輯器可以設定「按 Tab 自動轉成四個空白」,請務必開啟。混用 Tab 與空白是初學者最常見、也最難察覺的錯誤來源。

print 與註解:輸出與筆記

print() 是你最早、也最常用的工具,它把東西印到螢幕上。它很聰明,可以一次印多個值,用逗號隔開會自動補空白:

print("姓名:", "小明", "年齡:", 20)
# 輸出:姓名: 小明 年齡: 20

它也接受幾個好用的參數。sep 控制分隔符號,end 控制結尾(預設是換行 \n):

print("2026", "06", "14", sep="-")
# 輸出:2026-06-14

print("沒有換行", end="")
print("會接在同一行")
# 輸出:沒有換行會接在同一行

註解(comment) 是寫給人看、直譯器會略過的文字。Python 用 # 開頭表示單行註解:

# 這是一行註解,直譯器不會執行
radius = 5  # 也可以寫在程式碼後面,說明這個變數的意義
area = 3.14159 * radius ** 2  # ** 是次方運算

註解的目的是解釋「為什麼這樣做」,而不是複述程式碼字面意思。好的註解像旁白,幫未來的你(或同學)讀懂思路。反模式是寫一堆 x = x + 1 # x 加 1 這種廢話註解,那只是噪音。

變數即名牌:名字貼在物件上

很多教材把變數(variable)比喻成「裝東西的盒子」,這個比喻在 Python 裡其實會誤導你。更準確的心智模型是:變數是一張名牌(name tag),貼在某個物件(object)上。

x = 10
y = x      # y 也貼到同一個 10 上
x = 20     # x 改貼到新的 20,y 不受影響
print(x, y)
# 輸出:20 10

當你寫 y = x,並不是把 10 複製一份給 y,而是讓 y 這張名牌也指向 x 所指的那個 10。之後 x = 20 是把 x 撕下來、改貼到另一個物件 20,y 仍然貼在原本的 10

這個觀念在處理可變(mutable)物件如串列(list)時格外重要:

a = [1, 2, 3]
b = a          # b 和 a 是同一張清單的兩張名牌
b.append(4)
print(a)
# 輸出:[1, 2, 3, 4]   ← a 也變了!

因為 a 和 b 貼在同一個串列上,透過 b 修改內容,a 看到的也是修改後的結果。如果你真的想要一份獨立的副本,要明確複製:

a = [1, 2, 3]
b = a.copy()   # b 貼在一張新的、內容相同的清單上
b.append(4)
print(a, b)
# 輸出:[1, 2, 3] [1, 2, 3, 4]

記住「名牌貼在物件上」這個模型,你會少踩很多坑。

Python 是動態型別(dynamically typed):你不需要事先宣告變數是整數還是字串,名牌可以隨時改貼到不同型別的物件上。

v = 42          # 現在 v 貼在整數上
print(type(v))  # 輸出:<class 'int'>
v = "你好"      # 同一個名字改貼到字串上,完全合法
print(type(v))  # 輸出:<class 'str'>

這很方便,但也有代價——後面深入段會談這份自由背後的成本。

動手寫一段:BMI 計算機

把前面學到的東西組起來,寫一支完整、可執行的小程式。它請使用者輸入身高體重,算出 BMI(身體質量指數)並判斷區間。

# bmi.py — 簡易 BMI 計算機

# input() 讀取使用者輸入,回傳的一律是字串,要轉成數字
height_cm = float(input("請輸入身高(公分):"))
weight_kg = float(input("請輸入體重(公斤):"))

# 公式:BMI = 體重(kg) / 身高(m)^2
height_m = height_cm / 100
bmi = weight_kg / (height_m ** 2)

# round() 四捨五入到小數點後一位
print("你的 BMI 是:", round(bmi, 1))

if bmi < 18.5:
    print("體重過輕")
elif bmi < 24:
    print("正常範圍")
else:
    print("體重過重")

假設使用者輸入身高 170、體重 65,預期輸出:

請輸入身高(公分):170
請輸入體重(公斤):65
你的 BMI 是: 22.5
體重過重

這支小程式用到了輸入轉型、算術運算、if / elif / else 多重判斷與輸出,是把今天所有概念串起來的好練習。鼓勵你改改看:加一個「過重再細分」的條件,或把判斷包成一個函式。

常見錯誤與重點回顧

初學 Python,這幾個雷請特別留意:

  • 縮排混用 Tab 與空白:看起來對齊,直譯器卻報 IndentationErrorTabError。請設定編輯器一律用四個空白,全檔統一。
  • 以為變數是盒子b = a 對串列等可變物件來說,兩個名字指向同一份資料。要獨立副本請用 .copy() 或切片 a[:]
  • input() 回傳的是字串input() 永遠給你字串,要做數學運算前記得用 int()float() 轉型,否則 "5" + "3" 會得到 "53" 而不是 8
  • = 與 == 搞混= 是賦值(把名牌貼上去),== 是比較(問兩邊相不相等)。寫 if x = 5 會直接語法錯誤。
  • 中文全形符號混入程式碼:把程式裡的括號 () 或引號 "" 打成全形 ()「」,直譯器會報 SyntaxError。註解和字串內容可以放中文,但語法符號必須是半形。

深入探討(研究所視角)

前面說 Python 是「直譯語言」,但這個說法其實過於簡化。要真正理解 Python 的執行模型與效能特性,得拆開 CPython 的內部流程。

CPython 的直譯流程:原始碼不是直接被「逐行翻譯」。 當你執行一支 .py 檔,CPython 並不是一行一行邊讀邊翻成機器碼。它分成兩個階段。第一階段是編譯(compile):CPython 把原始碼先解析成抽象語法樹(AST, Abstract Syntax Tree),再編譯成一種中介表示——位元碼(bytecode)。位元碼是一組與平台無關的低階指令,不是 CPU 的機器碼,而是給 Python 虛擬機看的。第二階段才是執行:由 Python 虛擬機(PVM, Python Virtual Machine) 這個巨大的求值迴圈逐條讀取位元碼指令並執行。

你可以親眼看到位元碼:

import dis

def add(a, b):
    return a + b

dis.dis(add)
# 輸出(節錄,版本不同略有差異):
#   LOAD_FAST    a
#   LOAD_FAST    b
#   BINARY_OP    + (add)
#   RETURN_VALUE

LOAD_FASTBINARY_OP 這些就是位元碼指令,PVM 一條條照著做。

.pyc 檔的意義。 當你 import 一個模組時,CPython 會把編譯好的位元碼快取成 .pyc 檔,存在 __pycache__/ 資料夾裡。下次再 import,只要原始碼沒改,就直接載入 .pyc,跳過重新編譯,加快啟動。注意:這只是省下編譯步驟,不會讓執行本身變快——因為真正的瓶頸在 PVM 逐條解釋位元碼這一段。這也解釋了為何你直接執行的主程式(python main.py)不會產生 .pyc,但被它 import 的模組會。

動態型別的代價。 回到前面 v = 42 後又 v = "你好" 的例子。這份自由不是免費的。因為型別在執行期才能確定,PVM 每執行一個運算(例如 a + b)都必須在當下檢查 ab 到底是什麼型別、有沒有定義 +、該呼叫哪個方法。在靜態型別的編譯語言(如 C)裡,型別在編譯期就鎖定,a + b 可以直接編成一兩條 CPU 加法指令;而在 CPython 裡,同樣一個加法要經過多層型別查詢與方法分派(dispatch)。再加上 Python 的所有值都是堆積(heap)上的物件、帶著參考計數與型別資訊,這些都讓動態語言天生比靜態編譯語言慢上一個數量級。這就是 Python「慢」的根源。

直譯 vs 編譯,是光譜不是二分。 嚴格來說 CPython 是「先編譯成位元碼、再解釋執行」的混合模式。純編譯語言(C)一次把整支程式翻成機器碼再交給 CPU 跑,執行快但缺少互動性、跨平台需重編。純解釋(早期的 shell)逐行翻譯,最慢但最靈活。CPython 居中。而要突破 PVM 解釋的瓶頸,業界發展出即時編譯(JIT, Just-In-Time compilation)技術——例如 PyPy 在執行期把熱點程式碼動態編譯成機器碼,CPython 3.13 起也開始引入實驗性 JIT。理解了這條「原始碼 → AST → 位元碼 → PVM」的鏈條,你就能解釋為什麼 Python 開發快、執行慢,以及在做資料科學時,為什麼真正吃重的數值運算要交給用 C 寫成的 NumPy,而不是用純 Python 的迴圈硬算。

AI 共讀助教正在陪你讀:Python 入門與環境:從第一支程式到直譯器原理
嗨!我是這篇文章的共讀助教,只根據〈Python 入門與環境:從第一支程式到直譯器原理〉的內容回答。可以問我「解釋某段」「舉個例子」「出題考我」,或反白文中段落後點下方「解釋選取段落」。