Home
Explore Uedu
Student Console
Register as Member/Login
(2) In future presentations of the research findings, in addition to the course project website and public presentations, your real name and personal information will not appear in this research report. If you are interested in the research results, we can provide you with an executive summary after the study is completed.
問卷中心
Teacher Console
Course Setup
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

0

Local AI

--

CISOSE26 本地 AI UG26
政治大學 AQI 18 29°C

AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

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 入門與環境:從第一支程式到直譯器原理〉的內容回答。可以問我「解釋某段」「舉個例子」「出題考我」,或反白文中段落後點下方「解釋選取段落」。