在之前的兩篇文章中,我們探討了 Black 和 isort 這兩個工具,主要針對程式碼的格式進行調整,旨在提升程式碼的可讀性。高品質的程式碼有助於開發團隊能順利執行未來的維護任務。
而本篇,我將介紹另一種提高程式碼品質的工具,稱為 Linter。這個工具專門用來分析程式碼,並檢測出 Code Smell。以下是一些常見的 Code Smell:
Long Method
語句行數過於冗長,通常會造成邏輯複雜,開發者難以理解和維護。
Invalid Class Name
開發者通常會使用 CapWords 命名規範(例如,MyClass)來定義類別名稱。當開發者不遵循這些命名約定時,容易造成其他開發者的混淆,影響協作和維護。
Unused Variable
當其他開發者看到被定義但未使用的變數時,可能會產生混淆,誤以為這些變數應有某種用途,從而浪費時間試圖理解其意圖。
Magic Numbers
在先前的 zoneinfo
章節中,我們提到過程式碼中直接使用了數字,這些數字缺乏明確的上下文或說明,使其他開發者無法直觀地理解其含義或用途。例如,以下程式碼中的 1.15
並不明確,開發者無法得知這個數字所代表的具體意義。
def calculate_total_price(price):
return price * 1.15
Code Smell 可以被視為「警告信號」,儘管這些程式碼在表面上看似「正常」或「可運行」,但其實隱含著不良的設計或潛在問題。這些問題在短期內不一定會引發錯誤,但卻可能使程式碼變得難以閱讀和維護。而 Linter 工具能夠分析程式碼並識別 Code Smell,幫助開發者移除這些問題,從而提升程式碼的品質。
在 Python 生態系統中,有許多 Linter 可供使用,而這篇文章將專注於 Ruff。作為 Python 界的後起之秀,Ruff 雖然於 2022 年才問世,但因其獨特的特色迅速成為主流 Linter 之一。
分析速度
Ruff 的分析速度極快,遠超過其他 Linter。以我之前的專案為例,當我使用另一個主流的 Linter —— Pylint 時,完整分析整個專案約需 2 分鐘。而改用 Ruff 後,僅需約 1 秒鐘便可完成分析,極大地改善了開發體驗。
支援多種插件
Ruff 官方推出了多個插件,其中包括廣受使用的 Flake8 Plugin。這個插件可作為 Python Flake8 Linter 的替代品,讓開發者能使用 Flake8 的規則來分析程式碼。此外,還有使用 Pylint 檢查規則的 Pylint Plugin 以及檢查命名規則的 PEP8 Naming Plugin 等等。開發團隊可以根據具體需求,靈活組合多個插件的規則來進行程式碼分析。
接下來的範例中,我將教學如何設定 Ruff Plugin,並成功檢測出程式碼中的 Code Smell。
本次範例使用的是 Ruff 0.6.8 版本
poetry add ruff==0.6.8
首先,打開專案目錄中的 pyproject.toml
檔案,並在最下方新增 Ruff 的設定。除了預設的 F
插件外,本次範例還將額外採用 N
和 PLR
插件。
N
Plugin 主要用於檢查命名規則,幫助確保程式碼中的命名符合一致性和可讀性。PLR
Plugin 則作為替代 Pylint 的重構檢查規則,能夠檢測 Long Method 和 Magic Number 等 Code Smell。...
[tool.ruff.lint]
select = [
# Pyflakes
"F",
# PEP8-Naming
"N",
# Pylint-Refactor
"PLR",
]
接著,建立名為 main.py
的檔案,並使用指令 poetry run ruff check main.py
來分析程式碼。本次檢查會顯示兩個錯誤:
default_image_size
,但卻未被使用,這可能會讓開發者誤以為這個變數應該有某種用途,從而造成不必要的困惑。def is_qualified(length: int, width: int) -> bool:
default_image_size = 100 * 23
result = length * width
return result > 90