0%

Ruff:Python 開發的超級工具,讓你的程式碼又快又規範!

Ruff:Python 開發的超級工具,讓你的程式碼又快又規範!

在 Python 的世界裡,保持程式碼的整潔、一致和符合規範是每個開發者的共同目標。過去,我們可能需要安裝一堆工具:Flake8 檢查 Linting 規範、isort 排序 import 語句、Black 自動格式化程式碼,有時還要加上 mypy 進行型別檢查。這不僅安裝配置繁瑣,執行起來也常常拖慢速度。

直到 Ruff 的出現!作為一個用 Rust 編寫的 Python Linter 和 Formatter,Ruff 以其驚人的速度和整合多功能的能力,迅速成為 Python 社群的新寵兒。它不只快,還希望能成為你 Python 開發生態系統中不可或缺的「一站式」工具。

那麼,這個號稱 Python 開發超級工具的 Ruff 究竟有什麼能耐?讓我們一起深入了解它的各個面向,並探討如何將它融入你的開發流程中。

什麼是 Ruff?

Ruff 是一個極速的 Python Linter 和 Formatter,由 Astral (Rye 和 uv 的開發者) 開發,並用 Rust 語言編寫。它旨在提供一個比現有 Python Linting 和格式化工具更快、更整合的解決方案。

它的核心優勢包括:

  • 極致的速度:用 Rust 編寫,使得 Ruff 的執行速度比傳統的 Python 工具快 10 到 100 倍。這意味著在大型專案中,你可以頻繁執行檢查而不會感到延遲。
  • 功能整合:Ruff 不僅僅是一個 Linter。它整合了多個流行工具的功能,例如:
    • Linting:取代 Flake8Pylint 等。
    • Import 排序:取代 isort
    • 程式碼格式化:取代 Black
    • 自動修復:許多檢測到的問題可以直接透過 Ruff 自動修復。
  • 配置簡潔:Ruff 的配置通常比多個工具的配置更容易管理,可以在 pyproject.toml 中統一設定。

簡而言之,Ruff 的目標是成為 Python 專案程式碼品質管理的「瑞士刀」,且速度飛快。

Ruff Linter:快狠準的程式碼審查

Ruff 作為一個 Linter,其主要任務是分析你的 Python 程式碼,找出潛在的錯誤、風格問題、不良實踐以及可能導致 Bug 的地方。

它不僅實現了 Flake8 的所有常見規則 (如 EW 系列的 PEP 8 規範),還整合了許多其他流行 Linting 工具的規則集,例如:

  • Pyflakes (F):檢測邏輯錯誤,如未使用的變數、未定義的名稱。
  • pycodestyle (E, W):檢查 PEP 8 風格指南,如縮排、空格、行長度。
  • isort (I):檢查 import 語句的排序。
  • pylint (部分 PL):提供更深層的程式碼品質和錯誤檢測。
  • Bugbear (B):尋找潛在的 Bug。
  • Comprehensions (C4):建議更簡潔的推導式寫法。
  • Numpy-specific checks (NPY):針對 NumPy 程式碼的 Linting。
  • …還有更多!

如何使用 Ruff Linter?

最基本的用法:

1
ruff check .

這會檢查當前目錄及其所有子目錄下的 Python 檔案。

自動修復:

Ruff 最棒的功能之一是它的自動修復能力。許多 Linting 問題都可以被 ruff 自動修正:

1
ruff check --fix .

這會修正所有可以自動修復的問題,如移除未使用的 import、調整行尾空格等。

配置規則:

你可以在 pyproject.toml.ruff.toml 中配置 Ruff 的規則。例如,啟用或禁用特定的規則、設定忽略的路徑、調整行長度限制等:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# pyproject.toml
[tool.ruff]
line-length = 88 # 匹配 Black 的行長度
target-version = "py310" # 指定目標 Python 版本

# 啟用一些預設不啟用的規則集
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # Pyflakes
"I", # isort
"C4", # Comprehensions
"B", # Bugbear
"UP", # pyupgrade checks for modern Python syntax
]
ignore = [
"E501", # 忽略行長度檢查,如果Black或其他工具處理了
"W292", # 忽略文件末尾沒有換行
]

# 排除特定文件或目錄
exclude = [
".venv/",
"__pycache__/",
"build/",
"dist/",
]

透過簡單的配置,Ruff 就能為你的專案提供高效且全面的 Linting 服務。

Ruff Format:Black 的速度挑戰者

Ruff 在 2023 年底推出了內建的程式碼格式化功能,旨在取代 Black 並提供更快的格式化體驗。它的目標是與 Black 的輸出高度兼容,同時保持其閃電般的速度。

為什麼選擇 Ruff Formatter?

  • 速度:這是最主要的優勢。Ruff Formatter 比 Black 更快,這對於大型程式碼庫或需要頻繁格式化的場景(如 pre-commit hook)來說是巨大的提升。
  • 一站式工具:將 Linting 和格式化整合到一個工具中,減少了依賴和配置的複雜性。
  • 兼容性:Ruff Formatter 努力與 Black 保持 99% 的輸出兼容,這意味著你可以相對無痛地從 Black 遷移過來。

如何使用 Ruff Formatter?

格式化程式碼:

1
ruff format .

這會格式化當前目錄及其所有子目錄下的 Python 檔案。

檢查檔案是否已格式化(不會修改檔案):

1
ruff format --check .

與 Linter 結合使用(先修復 Linting 問題,再格式化):

1
ruff check --fix . && ruff format .

pyproject.toml 中,Ruff 的格式化器會自動繼承 Linter 的 line-length 設定。

Ruff 與 Pre-commit Hook

將 Ruff 與 Git 的 pre-commit hook 結合使用是保持程式碼品質的最佳實踐。這意味著在每次提交 (commit) 程式碼之前,Ruff 會自動檢查並格式化你的程式碼,確保只有符合規範的程式碼才能被提交。

設定步驟:

  1. 安裝 pre-commit

    如果你還沒安裝,先安裝 pre-commit 工具:

    1
    pip install pre-commit
  2. 在專案中初始化 pre-commit

    在你的專案根目錄執行:

    1
    pre-commit install

    這會在 .git/hooks/ 目錄下創建一個 pre-commit 腳本。

  3. 創建 .pre-commit-config.yaml 檔案:

    在你的專案根目錄下,創建一個名為 .pre-commit-config.yaml 的文件,並添加以下內容:

    1
    2
    3
    4
    5
    6
    7
    8
    # .pre-commit-config.yaml
    repos:
    - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.4.5 # 替換為當前最新的 Ruff 版本
    hooks:
    - id: ruff
    args: [--fix, --exit-non-zero-on-fix] # 執行 Linting 並自動修復
    - id: ruff-format # 執行格式化
    • id: ruff:執行 Linting 檢查。--fix 讓 Ruff 自動修復問題。--exit-non-zero-on-fix 確保如果有檔案被修復,pre-commit 會失敗,促使你重新 add 被修改的檔案並再次提交。
    • id: ruff-format:執行格式化。如果檔案未經格式化,pre-commit 會失敗,並且 ruff format 會自動格式化檔案,你只需重新 add 並提交。

    現在,每次你執行 git commit 時,Ruff 都會自動運行 Linting 檢查和格式化,確保你的程式碼在進入版本控制之前就是乾淨且規範的。

Ruff 的最佳實踐

要最大化 Ruff 的效益,可以考慮以下最佳實踐:

  1. 整合到 pyproject.toml:將所有 Ruff 配置(包括 Linting 規則和 Formatter 相關設定)集中在 pyproject.toml 中的 [tool.ruff] 部分。這有助於專案配置的統一和可發現性。
  2. Black 遷移策略:如果你之前使用 Black,可以直接將 ruff format 納入 pre-commit。由於 Ruff 和 Black 的輸出高度兼容,遷移通常非常順利。在過渡期,確保你的 CI/CD 流程也已切換到 Ruff,以避免不一致。
  3. 逐步啟用規則:Ruff 支援大量的 Linting 規則。剛開始時,你可以從較少的、常用的規則集開始(例如 E, W, F, I),然後根據團隊的需要逐步啟用更多規則。不要一次啟用所有規則,這可能會產生大量警告,讓團隊難以消化。
  4. 教育團隊成員:確保所有團隊成員都了解並使用 Ruff。統一的工具和規範能極大提升團隊的開發效率和程式碼品質。
  5. 結合 CI/CD:除了 pre-commit hook,務必將 ruff check --diff (在 CI 中使用,檢查差異而不直接修改檔案) 和 ruff format --check (在 CI 中使用,檢查格式化狀態) 整合到你的 CI/CD 管線中。這能確保即使有人繞過了 pre-commit,不符合規範的程式碼也不會被部署。
  6. 善用 --fix--fix-only:對於日常開發,ruff check --fix 非常有用。而 ruff check --fix-only 則只執行自動修復,不報告無法修復的問題,這在 CI/CD 中進行強制格式化時很有用。

結論

Ruff 的出現,無疑為 Python 開發者帶來了前所未有的效率提升。它將多個獨立的 Linting 和格式化工具的功能集於一身,並以驚人的速度執行。無論是提升個人開發效率,還是確保團隊程式碼品質的一致性,Ruff 都展現出了巨大的潛力。

透過將 Ruff 融入你的日常開發流程和 CI/CD 管線中,你將能夠以更少的時間,維護更高品質的 Python 程式碼。Python 的工具鏈,正因為像 Ruff 這樣的創新而變得越來越好。你準備好讓 Ruff 成為你的新夥伴了嗎?