常用標準庫與生態:Python 自帶的工具箱
從 math、random、datetime 到 pip 與虛擬環境,用一個值班表任務串起 Python 的「batteries included」哲學
從零開始的「每日值班表」:標準庫就是你的工具箱
假設今天助教請你寫一個小程式:抓出這學期某段日期區間裡的所有週五,從一份名單裡隨機抽出值班同學,再把結果存成 JSON 檔交出去。聽起來要寫很多東西?其實一行第三方套件都不用裝——Python 自帶的「標準庫(standard library)」已經把日期、隨機、檔案、資料格式都準備好了。
Python 有個外號叫「batteries included(內建電池)」,意思是裝好直譯器的當下,你就已經擁有一整箱可以直接用的工具。這篇文章我們先把最常用的幾個標準庫摸熟,再走進 pip、虛擬環境與第三方套件的生態。請打開你的終端機,邊讀邊敲,這些程式碼每一段都可以直接執行。

import:把工具從箱子裡拿出來
標準庫的東西不會自動出現在你的程式裡,要用 import 把對應的模組(module)拿進來。先看三種慣例寫法:
import math # 匯入整個模組,用 math.sqrt 呼叫
from random import choice # 只匯入需要的名字,直接用 choice
import datetime as dt # 取別名,之後用 dt 代替 datetime
print(math.sqrt(16)) # 輸出:4.0
print(choice([1, 2, 3])) # 輸出:1、2 或 3 其中之一
依照 PEP 8 的精神,import 一律放在檔案最上方,而且分三組、組間空一行:先標準庫,再第三方套件,最後是自己專案的模組。
# 標準庫
import os
import json
# 第三方套件
import requests
# 自己的專案模組
from myproject import utils
反模式:千萬不要用 from math import *。星號會把模組裡所有名字一次倒進你的命名空間,很容易和你自己的變數撞名,讀程式的人也分不清 sqrt 到底是哪來的。明確寫出來,永遠比偷懶安全。
math 與 random:數學與隨機
math 提供超越基本四則運算的數學函式,random 則負責產生隨機性。
import math
print(math.pi) # 輸出:3.141592653589793
print(math.ceil(4.1)) # 輸出:5 (無條件進位)
print(math.floor(4.9)) # 輸出:4 (無條件捨去)
print(math.gcd(12, 18)) # 輸出:6 (最大公因數)
print(math.factorial(5)) # 輸出:120
random 的常用四招:
import random
print(random.randint(1, 6)) # 輸出:1 到 6 的整數(含兩端)
print(random.random()) # 輸出:0.0 到 1.0 之間的浮點數
print(random.choice(['a', 'b', 'c'])) # 輸出:隨機抽一個元素
names = ['小安', '阿哲', '怡君', '宗翰']
random.shuffle(names) # 原地洗牌,不回傳新串列
print(names) # 輸出:順序被打亂的名單
小提醒:random 產生的是「偽隨機」,適合教學、模擬、抽籤,但不可用於密碼或金鑰。需要密碼學等級的安全亂數時,請改用標準庫裡的 secrets 模組。
datetime:和時間打交道
處理日期時間是日常任務,datetime 模組讓你不用自己算閏年。
from datetime import datetime, date, timedelta
today = date.today()
print(today) # 輸出:2026-06-14(依當天而定)
# 兩週後是哪天?timedelta 表示一段時間差
later = today + timedelta(days=14)
print(later) # 輸出:2026-06-28
# 取得目前的完整時間戳,並格式化輸出
now = datetime.now()
print(now.strftime('%Y/%m/%d %H:%M')) # 輸出:2026/06/14 09:30
weekday() 回傳星期幾,星期一是 $0$、星期日是 $6$。我們用它來找出開頭情境裡的所有週五:
from datetime import date, timedelta
start = date(2026, 6, 1)
end = date(2026, 6, 30)
fridays = []
d = start
while d <= end:
if d.weekday() == 4: # 4 代表星期五
fridays.append(d)
d += timedelta(days=1)
print(fridays)
# 輸出:[datetime.date(2026, 6, 5), ..., datetime.date(2026, 6, 26)]
os 與 json:檔案路徑與資料交換
os 與其子模組 os.path 處理作業系統相關操作,例如讀環境變數、組路徑。
import os
print(os.getcwd()) # 輸出:目前工作目錄
print(os.path.join('data', 'log.txt')) # 輸出:data/log.txt(自動用對的分隔符)
print(os.path.exists('data/log.txt')) # 輸出:True 或 False
用 os.path.join 而不是手動拼字串 'data' + '/' + 'log.txt',因為 Windows 用反斜線、Linux 用斜線,交給標準庫處理才不會在別人的電腦上爆掉。
json 負責 Python 物件和 JSON 文字之間的轉換,這是程式之間交換資料的通用語言:
import json
data = {'班級': '通識101', '值班': ['小安', '怡君'], '人數': 2}
# dump 成字串(ensure_ascii=False 才能正常顯示中文)
text = json.dumps(data, ensure_ascii=False, indent=2)
print(text)
# 輸出:
# {
# "班級": "通識101",
# "值班": ["小安", "怡君"],
# "人數": 2
# }
# 字串轉回 Python 物件
back = json.loads(text)
print(back['人數']) # 輸出:2
collections:更好用的資料結構
collections 是標準庫裡的隱藏寶藏,提供比內建型別更貼心的容器。最常用的是 Counter 和 defaultdict。
Counter 一行就能統計次數:
from collections import Counter
votes = ['A', 'B', 'A', 'C', 'A', 'B']
tally = Counter(votes)
print(tally) # 輸出:Counter({'A': 3, 'B': 2, 'C': 1})
print(tally.most_common(1)) # 輸出:[('A', 3)]
defaultdict 讓你不用每次都檢查鍵是否存在:
from collections import defaultdict
groups = defaultdict(list) # 預設值是空串列
pairs = [('一年級', '小安'), ('一年級', '阿哲'), ('二年級', '怡君')]
for grade, name in pairs:
groups[grade].append(name) # 鍵不存在時自動建一個空串列
print(dict(groups))
# 輸出:{'一年級': ['小安', '阿哲'], '二年級': ['怡君']}
如果用普通的 dict,上面那行 groups[grade].append(...) 在鍵還不存在時會直接拋出 KeyError,你得多寫一段判斷。defaultdict 幫你省掉了。
動手寫一段:完整的值班表產生器
現在把前面所有模組組起來,完成開頭那個任務——找出某月所有週五、隨機指派值班同學、存成 JSON:
import json
import random
from datetime import date, timedelta
from collections import Counter
def make_duty_roster(year, month, students, seed=42):
"""為指定月份的每個週五隨機指派一位值班同學。"""
random.seed(seed) # 固定種子,讓結果可重現
# 1. 找出該月所有週五
d = date(year, month, 1)
fridays = []
while d.month == month:
if d.weekday() == 4:
fridays.append(d.isoformat())
d += timedelta(days=1)
# 2. 為每個週五隨機抽一位同學
roster = {day: random.choice(students) for day in fridays}
# 3. 統計誰被排到最多次
workload = Counter(roster.values())
return roster, workload
students = ['小安', '阿哲', '怡君', '宗翰']
roster, workload = make_duty_roster(2026, 6, students)
print(json.dumps(roster, ensure_ascii=False, indent=2))
print('值班次數統計:', dict(workload))
# 輸出:
# {
# "2026-06-05": "怡君",
# "2026-06-12": "小安",
# "2026-06-19": "宗翰",
# "2026-06-26": "怡君"
# }
# 值班次數統計: {'怡君': 2, '小安': 1, '宗翰': 1}
短短三十行,就用了五個標準庫模組合作完成一個實用工具。注意我們用了 random.seed(42),這樣每次跑結果都一樣,方便除錯與測試——這是寫模擬程式很重要的習慣。
走出標準庫:pip 與第三方套件生態
標準庫很強,但全世界 Python 開發者還貢獻了數十萬個第三方套件,集中放在官方倉庫 PyPI(Python Package Index)。要安裝它們,用 Python 內建的套件管理工具 pip,這些指令在終端機(不是 Python 直譯器裡)執行:
pip install requests # 安裝最新版
pip install "requests==2.31.0" # 安裝指定版本
pip install --upgrade requests # 升級到最新版
pip list # 列出已安裝的套件
pip show requests # 看某個套件的詳細資訊
裝好之後就能像標準庫一樣 import。例如 requests 讓發 HTTP 請求變得非常直覺:
import requests
resp = requests.get('https://api.github.com')
print(resp.status_code) # 輸出:200
print(resp.json()['current_user_url']) # 輸出:https://api.github.com/user
幾個你很快會遇到的明星套件:資料分析的 pandas 與 numpy、繪圖的 matplotlib、網頁框架 flask 與 django、爬蟲解析 beautifulsoup4。它們都不是標準庫,要先 pip install 才有。
虛擬環境:每個專案各用各的
如果你直接把所有套件都裝進系統 Python,遲早會出事:A 專案需要 requests 2.20,B 專案需要 requests 2.31,兩者裝在一起就會打架。解法是虛擬環境(virtual environment)——為每個專案建立一個獨立、乾淨的 Python 環境。
標準庫內建的 venv 模組就能做到,這幾行在終端機執行:
# 1. 在專案資料夾裡建立虛擬環境(資料夾名慣例叫 venv 或 .venv)
python -m venv .venv
# 2. 啟動它
# macOS / Linux:
source .venv/bin/activate
# Windows(PowerShell):
.venv\Scripts\Activate.ps1
# 3. 啟動後 pip install 的東西只會裝進這個環境
pip install requests pandas
# 4. 把目前環境的套件清單匯出,方便別人重現
pip freeze > requirements.txt
# 5. 別人拿到你的專案,一行還原所有相依套件
pip install -r requirements.txt
# 6. 不用了就離開
deactivate
啟動虛擬環境後,你的終端機提示字元前面通常會出現 (.venv),代表現在的 python 和 pip 都指向這個隔離環境。養成「每個專案一個虛擬環境」的習慣,是專業 Python 開發的基本功。
常見錯誤
- 用
from module import *:污染命名空間、撞名、別人看不懂名字哪來的。請明確匯入需要的名字。 - 手動拼接檔案路徑:
'data' + '/' + name在 Windows 會壞掉。永遠用os.path.join(或更現代的pathlib)。 - json 存中文變亂碼:忘了加
ensure_ascii=False,中文會變成\uXXXX。記得補上這個參數。 - 把套件裝進系統 Python:沒用虛擬環境,不同專案的相依版本互相衝突,最後整台電腦的 Python 一團亂。先
python -m venv再說。 - 混淆終端機指令與 Python 程式碼:
pip install是在終端機(shell)打的,不是寫在.py檔裡或貼進直譯器。初學者很常搞混這兩個地方。
深入探討(研究所視角)
標準庫 vs 第三方套件的取捨。標準庫的最大優勢是「零安裝、版本跟著直譯器走」,任何裝了 Python 的機器都能跑,特別適合工具腳本與不想引入相依的場景。但標準庫的更新節奏綁定 CPython 的釋出週期(約一年一次),有些模組(例如舊版的 urllib)介面笨重,這正是 requests 這類第三方套件存在的理由——它們疊代快、API 更人性化。判斷準則是:能用標準庫優雅解決就別引入相依;但若第三方套件能大幅降低複雜度且維護活躍,引入它是合理的工程決策。每多一個相依,就多一份未來要維護、要追資安更新的責任。
版本與相依管理的本質。pip install requests 不只裝 requests,還會遞迴解析它依賴的 urllib3、certifi 等套件,這叫相依樹(dependency tree)。多數套件遵循語意化版本(Semantic Versioning),版號 MAJOR.MINOR.PATCH 分別代表「破壞性變更/向後相容的新功能/修錯」。因此在 requirements.txt 裡用 requests>=2.31,<3.0 這種範圍約束,意思是「接受相容更新,但拒絕可能破壞 API 的大版號跳躍」。當不同套件對同一個間接相依要求互斥版本時,就會發生「相依地獄(dependency hell)」——這也是 pip freeze 鎖定確切版本、以及 Poetry、uv、pip-tools 等現代工具用 lockfile 鎖定整棵相依樹的原因:確保你今天、隊友明天、伺服器下個月跑的是完全相同的套件組合。
為何虛擬環境要做隔離。Python 透過 sys.path 這個搜尋路徑清單來找模組,import 時會依序在這些目錄裡尋找。虛擬環境的本質,就是建立一套獨立的 site-packages 目錄並改寫 sys.path,讓這個環境的 pip 只把套件裝進它自己的角落,import 也只在那裡找。這帶來三個關鍵好處:其一,專案間的相依版本完全隔離,A 專案的 requests 2.20 不會影響 B 專案的 2.31;其二,不需要系統管理員權限就能裝套件,也不會污染作業系統自帶的 Python(很多 Linux 系統工具依賴它,亂裝會弄壞系統);其三,requirements.txt 或 lockfile 加上乾淨的虛擬環境,等於把「可重現的執行環境」變成可交付的工程資產——這正是邁向容器化(Docker)與持續整合的第一步。理解了 sys.path 與 site-packages 的運作,你就會明白:虛擬環境不是什麼神祕魔法,而是對模組搜尋機制的一次優雅利用。