跳转至

Ruff Python 代码检查与格式化

一句话概述:Ruff 是用 Rust 写的 Python 代码检查器和格式化器,比 Flake8 快 100 倍,一个工具替代 Flake8 + Black + isort + pyupgrade 等十几个工具,零依赖单文件。

核心知识点

概念白话解释
Linter(检查器)扫描代码找问题:Bug、风格、安全漏洞
Formatter(格式化器)统一代码格式:缩进、换行、引号风格
900+ 条规则内置 Flake8、isort、pyupgrade 等几十个工具的规则
Rust 实现用 Rust 写的,极快,大项目也是毫秒级
零依赖不需要 Python 运行时,装一个二进制就行
pyproject.toml推荐的配置方式,所有 Ruff 设置写在一个文件里

安装配置

# 方式一:pip(最常用)
pip install ruff  # 安装 Ruff

# 方式二:pipx(全局隔离安装)
pipx install ruff

# 方式三:uv(最快)
uv tool install ruff

# 方式四:Homebrew
brew install ruff

# 方式五:conda
conda install -c conda-forge ruff

# 检查版本
ruff --version  # 查看安装的版本(当前最新 v0.15.x)

配置文件

# pyproject.toml - 推荐的配置方式
[tool.ruff]
target-version = "py311"  # 目标 Python 版本
line-length = 88  # 每行最大长度(和 Black 一致)
indent-width = 4  # 缩进宽度
fix = true  # 默认自动修复

# 排除目录
exclude = [
    ".venv",
    "migrations",
    "__pycache__",
    "*.egg-info",
]

[tool.ruff.lint]
# 启用的规则集
select = [
    "E",    # pycodestyle 错误
    "W",    # pycodestyle 警告
    "F",    # Pyflakes
    "I",    # isort(导入排序)
    "N",    # pep8-naming(命名规范)
    "UP",   # pyupgrade(现代化语法)
    "B",    # flake8-bugbear(常见 Bug)
    "S",    # flake8-bandit(安全检查)
    "C4",   # flake8-comprehensions(推导式优化)
    "SIM",  # flake8-simplify(代码简化)
    "RUF",  # Ruff 自己的规则
]

# 忽略的规则
ignore = [
    "E501",   # 行太长(用格式化器处理)
    "S101",   # assert 使用(测试里需要用)
]

# 每个文件的规则覆盖
[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["S101", "S106"]  # 测试文件忽略安全检查
"__init__.py" = ["F401"]  # __init__.py 忽略未使用导入

[tool.ruff.lint.isort]
known-first-party = ["myproject"]  # 第一方库(你自己的包)

[tool.ruff.format]
quote-style = "double"  # 双引号
indent-style = "space"  # 空格缩进
skip-magic-trailing-comma = false  # 保留尾逗号
line-ending = "auto"  # 自动检测换行符

基本使用

代码检查(Lint)

# 检查代码
ruff check .  # 检查当前目录所有 Python 文件
ruff check src/  # 检查指定目录
ruff check script.py  # 检查指定文件

# 自动修复
ruff check . --fix  # 自动修复可修复的问题
ruff check . --fix --unsafe-fixes  # 包括不安全的修复(需人工确认)

# 查看详情
ruff check . --show-fixes  # 显示每个问题的修复建议
ruff check . --statistics  # 显示统计信息

代码格式化(Format)

# 格式化代码
ruff format .  # 格式化当前目录
ruff format src/  # 格式化指定目录

# 检查格式(不修改,只报告)
ruff format . --check  # CI 中用,有不规范的就报错
ruff format . --diff  # 显示会做的修改(不实际修改)

示例:Ruff 能发现什么

# 修复前 ❌
import os  # F401: 未使用的导入
import json
from typing import List, Dict  # UP006: 用 list/dict 替代 typing.List/Dict

def processData(data):  # N802: 函数名应该用小写加下划线
    result = []
    for item in data:
        if item != None:  # E711: 应该用 is not None
            x = item["value"]
            if x == True:  # E712: 应该用 is True
                result.append(x)
    return result

names = list()  # C408: 直接用 [] 代替 list()

# 修复后 ✅(ruff check --fix)
import json

def process_data(data):
    result = []
    for item in data:
        if item is not None:
            x = item["value"]
            if x is True:
                result.append(x)
    return result

names = []

高级用法

导入排序(替代 isort)

# 修复前 ❌ 导入混乱
import json
from myproject.utils import helper
import os
from pathlib import Path
import requests
from myproject.models import User

# 修复后 ✅ ruff 自动排序
import json  # 1. 标准库
import os
from pathlib import Path

import requests  # 2. 第三方库

from myproject.models import User  # 3. 本项目
from myproject.utils import helper

Pre-commit 集成

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.15.0  # 使用最新版本
    hooks:
      - id: ruff  # 代码检查
        args: [--fix]  # 自动修复
      - id: ruff-format  # 代码格式化
pip install pre-commit  # 安装 pre-commit
pre-commit install  # 安装到 git hooks
# 每次 git commit 都会自动检查和格式化

VS Code 集成

// .vscode/settings.json
{
  "[python]": {
    "editor.formatOnSave": true,  // 保存时格式化
    "editor.defaultFormatter": "charliermarsh.ruff",  // 用 Ruff 格式化
    "editor.codeActionsOnSave": {
      "source.fixAll.ruff": "explicit",  // 保存时自动修复
      "source.organizeImports.ruff": "explicit"  // 保存时排序导入
    }
  }
}

块级禁用规则(v0.15 新功能)

# ruff: disable[N803]  # 从这里开始禁用 N803 规则
def MyFunction(A, B):  # 不会报命名警告
    return A + B
# ruff: enable[N803]  # 恢复启用

# noqa 行级禁用
x = 1  # noqa: F841  # 这一行忽略 F841 规则

CI/CD 集成

# .github/workflows/lint.yml
name: Lint
on: [push, pull_request]
jobs:
  ruff:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/ruff-action@v3  # 官方 GitHub Action
        with:
          args: "check"  # 检查代码
      - uses: astral-sh/ruff-action@v3
        with:
          args: "format --check"  # 检查格式

常见报错

报错信息原因解决方案
F401 imported but unused导入了但没用删掉没用的 import,或在 __init__.py# noqa
E501 line too long行太长ruff format 自动换行
I001 import block not sorted导入没排序ruff check --fix 自动排序
UP006 use list instead of List旧式类型注解ruff check --fix 自动升级
和 Black 格式不同配置差异Ruff 默认兼容 Black,检查 line-length 设置
规则太多太烦选了太多规则["E", "F", "I"] 开始,逐步添加

速查表

# CLI 命令
ruff check .              # 检查代码
ruff check . --fix        # 检查并修复
ruff format .             # 格式化代码
ruff format . --check     # 检查格式(不修改)
ruff format . --diff      # 显示差异
ruff rule E501            # 查看某条规则的说明
ruff linter               # 列出所有可用的 linter
ruff version              # 查看版本

# 常用规则集代码
E/W    # pycodestyle(PEP8 风格)
F      # Pyflakes(逻辑错误)
I      # isort(导入排序)
N      # pep8-naming(命名规范)
UP     # pyupgrade(语法现代化)
B      # flake8-bugbear(常见 Bug)
S      # flake8-bandit(安全)
C4     # flake8-comprehensions(推导式)
SIM    # flake8-simplify(简化)
RUF    # Ruff 自有规则

# 行内控制
# noqa            # 忽略本行所有规则
# noqa: F401      # 忽略本行特定规则
# ruff: noqa      # 忽略整个文件
# type: ignore    # 忽略类型检查(mypy)

参考:Ruff 官网 | GitHub | 规则列表