本文 AI 產出,尚未審核
Python 基本語法 – 註解(#、docstring)
簡介
在程式開發的過程中,註解是維護、協作與除錯不可或缺的工具。它不會被 Python 直譯器執行,卻能向閱讀程式碼的人傳遞意圖、說明演算法步驟、或提供使用說明。對於 初學者,適當的註解能加速學習;對 中級開發者,則是撰寫可讀、可維護程式的基礎。
Python 的註解主要分為兩類:
- 單行註解:以
#開頭,適合說明單行或區塊的目的。 - 文件字串(Docstring):使用三重引號 (
""" … """或''' … ''') 包住的字串,通常放在模組、類別或函式的最前面,作為 自動化文件產生工具(如help()、Sphinx)的來源。
本篇將深入探討這兩種註解的寫法、最佳實踐與常見陷阱,並提供多個實務範例,幫助你在日常開發中寫出更清晰、更專業的程式碼。
核心概念
1. 單行註解(#)
- 語法:
#後面的文字直到行尾皆被視為註解。 - 特點:簡潔、即時,可放在程式碼行尾或獨立成行。
- 使用時機:說明「為什麼」而非「做了什麼」,避免重複程式碼本身的意圖。
範例 1:行尾註解
total = sum(values) # 計算所有值的總和
範例 2:區塊說明
# ------------------------------
# 讀取 CSV 檔案並過濾資料
# ------------------------------
import csv
with open('data.csv', newline='') as f:
reader = csv.DictReader(f) # 產生字典型別的迭代器
filtered = [row for row in reader if int(row['age']) > 30]
範例 3:暫時停用程式碼(debug 時常用)
# result = expensive_calculation() # 先不執行,觀察前面的輸出
print("程式已執行到此")
小技巧:在 IDE 或編輯器中,使用快捷鍵(如
Ctrl+/)一次性切換多行註解,可大幅提升除錯效率。
2. 文件字串(Docstring)
- 語法:在模組、類別或函式的第一行,使用三重單引號
'''或雙引號"""包住的字串。 - 屬性:Python 會將它儲存於
__doc__屬性,供help()、inspect模組或第三方文件產生工具讀取。 - 風格:依照 PEP 257 建議,使用 第一人稱敘述(描述「做什麼」),並在必要時加入 參數說明、回傳值、例外。
範例 4:函式 Docstring(簡潔版)
def add(a: int, b: int) -> int:
"""回傳兩個整數的加總。"""
return a + b
範例 5:模組 Docstring(完整範例)
"""utility.py
提供常用的字串處理函式,包含:
- `slugify()`:將中文或特殊字元轉為 URL 安全的 slug。
- `truncate()`:根據字元數或寬度截斷字串。
此模組僅作為教學示例,未包含完整錯誤處理。
"""
def slugify(text: str) -> str:
"""將文字轉為 URL 安全的 slug。
1. 轉小寫
2. 去除前後空白
3. 替換空白與特殊字元為 '-'
4. 移除非 ASCII 字元
Parameters
----------
text: str
原始文字
Returns
-------
str
處理後的 slug
"""
import re, unicodedata
text = unicodedata.normalize('NFKD', text).encode('ascii', 'ignore').decode()
text = re.sub(r'\s+', '-', text.strip().lower())
return re.sub(r'[^a-z0-9\-]', '', text)
範例 6:類別 Docstring(包含屬性說明)
class Counter:
"""簡易計數器,提供遞增、遞減與重設功能。
Attributes
----------
value : int
目前的計數值,預設為 0。
"""
def __init__(self, start: int = 0):
"""建立 Counter 物件。
Parameters
----------
start : int, optional
初始值,預設為 0。
"""
self.value = start
def inc(self, step: int = 1) -> None:
"""將計數值遞增 `step`。"""
self.value += step
def dec(self, step: int = 1) -> None:
"""將計數值遞減 `step`。"""
self.value -= step
def reset(self) -> None:
"""將計數值重設為 0。"""
self.value = 0
常見陷阱與最佳實踐
| 陷阱 | 說明 | 解決方案 |
|---|---|---|
| 把程式說明寫成註解 | 把「這行程式在做什麼」寫在 # 後,會造成資訊冗餘。 |
讓程式本身盡量自敘(使用易懂的變數名),僅在為何需要這樣寫時加註解。 |
| 忘記更新註解 | 程式改版後,舊註解仍保留舊資訊,誤導閱讀者。 | 每次修改程式碼時,同步檢查相關註解;使用 IDE 的 TODO 標記提醒。 |
| 把 Docstring 用作普通註解 | 在函式內部大量使用 """ … """,實際上會產生字串物件(浪費記憶體)。 |
只在 模組、類別、函式 開頭使用 Docstring;其餘情況使用 #。 |
| 縮排不一致 | Docstring 內的縮排與程式碼不對齊,會導致 inspect.getsource() 產生不美觀的文件。 |
依照 PEP 257,第一行的三重引號與程式碼同層,內容縮排 4 個空格。 |
| 過長的單行註解 | 單行註解超過 79 個字元,破壞可讀性。 | 折行:使用多行 #,或將說明搬到 Docstring。 |
最佳實踐清單
- 保持簡潔:單行註解不超過 72 個字元。
- 使用動詞原形:
# 計算總和→# 計算總和(說明動作)。 - 統一風格:全專案使用同一種 Docstring 風格(Google、NumPy、reST)。
- 自動化檢查:結合
flake8,pylint,pydocstyle之類的 lint 工具,確保註解符合規範。 - 與版本控制結合:在 PR(Pull Request)說明中標註「新增/更新註解」的項目,讓 reviewer 能聚焦於說明的正確性。
實際應用場景
開源函式庫
- 使用 Docstring 撰寫 API 說明,讓使用者透過
help()或 IDE 的即時提示(IntelliSense)直接取得文件。 - 例:
pandas.DataFrame.head()的說明即來自 Docstring。
- 使用 Docstring 撰寫 API 說明,讓使用者透過
大型專案維護
- 團隊成員在接手舊程式時,靠 清晰的註解 快速了解商業邏輯或特殊演算法。
- 使用
# TODO:、# FIXME:標記未完成或需改進的部分,配合 CI(持續整合)檢測。
自動化測試與文件生成
pytest可以透過函式的 Docstring 產生測試報告;Sphinx 可直接把 Docstring 轉成 HTML、PDF。- 範例:在
setup.cfg中設定sphinx.ext.autodoc,自動抽取模組說明。
教學與示範程式
- 在教學筆記或部落格文章中,搭配 程式碼區塊 前後加上說明性註解,讓讀者一步步跟隨。
- 例如:在 Jupyter Notebook 中,使用
# %%分割程式區塊,結合註解說明每個步驟。
總結
- 單行註解 (
#) 適用於快速說明、除錯與暫時停用程式碼;Docstring 則是正式的文件來源,應放在模組、類別、函式的最前端。 - 正確的註解 提升可讀性、降低維護成本,尤其在多人協作或長期專案中更顯重要。
- 避免常見陷阱(過時、冗長、錯置),並遵守 PEP 8、PEP 257 以及團隊的風格指南。
- 結合自動化工具(
flake8、pydocstyle、Sphinx)可讓註解品質保持一致,並自動產出專業文件。
透過本篇的概念與範例,你現在應該能在自己的 Python 程式中 自信地加入註解與 Docstring,讓程式碼不僅能執行,更能被人輕鬆理解與維護。祝你寫程式愉快,寫出乾淨、可讀、可維護的 Python 代碼!