使用 ruff 提升 Python 代码质量
ruff 介绍
Ruff 是一个 Python linter + formatter 工具。可以用来检测 Python 语法问题与格式化 Python 代码。
想要全面了解 Ruff,需要具体知晓, 它能够做到哪些事、取代哪些工具。
什么是 Linter
Linter 是一种代码检查工具,可以帮助我们改进代码:包括检查代码中的语法错误、编码风格问题和潜在的漏洞,并提供建议和修正方法。通过使用 Linter 工具,开发者可以快速地发现并修正程序中的错误,提高代码的质量。
Python 常见的 Linter 工具包括 Flake8, Pylint 等等。
什么是 Formatter
Code Formatter(代码格式化工具)是一种自动将源代码按照特定风格规范进行排版、缩进、换行、空格处理等操作的工具。它的目标是让代码风格统一,提高可读性,并减少团队协作中因风格差异带来的争议。
Python 常见的 Formatter 工具包括 Black, YAPF 等等。
安裝使用
对于没有安装 Ruff 的人,请运行以下命令:
pip install ruff
要在 Python 文件中使用格式化程序功能,可以运行 ruff format /path/to/file.py
命令,它将格式化该文件。
要格式化目录中的所有文件,可以运行 ruff format .
命令。
linter
1、要将 Ruff 作为 linter 运行,请尝试以下任一操作:
ruff check . # 检查当前目录(以及任何子目录)中的所有文件
ruff check path/to/code/ # 对 `/path/to/code`(及任何子目录)中的所有文件进行检查
ruff check path/to/code/*.py # 检查 `/path/to/code` 中的所有 `.py` 文件
ruff check path/to/code/to/file.py # 检查 `file.py`
ruff check @arguments.txt # 使用输入文件 Lint,将其内容视为以新行分隔的命令行参数。
2、或者,将 Ruff 作为格式化程序运行:
ruff format . # 格式化当前目录(及任何子目录)中的所有文件
ruff format path/to/code/ # 格式化 `/path/to/code`(及任何子目录)中的所有文件
ruff format path/to/code/*.py # 格式化 `/path/to/code` 中的所有 `.py` 文件
ruff format path/to/code/to/file.py # 格式化 `file.py`.
ruff format @arguments.txt # 使用输入文件格式,将其内容视为以新行分隔的命令行参数。
例子
如果有一个这样的代码:
log = new_log(tracker["ip_address"], tracker["request_url"], tracker["request_port"],
tracker["request_path"], tracker["request_method"],
tracker["browser_type"], tracker["operating_system"], tracker["request_time"])
运行指令检测语法问题
$ ruff check main.py
main.py:1:7: F821 Undefined name `new_log`
main.py:1:15: F821 Undefined name `tracker`
main.py:1:38: F821 Undefined name `tracker`
main.py:1:62: F821 Undefined name `tracker`
main.py:2:15: F821 Undefined name `tracker`
main.py:2:40: F821 Undefined name `tracker`
main.py:3:15: F821 Undefined name `tracker`
main.py:3:40: F821 Undefined name `tracker`
main.py:3:69: F821 Undefined name `tracker`
Found 9 errors.
format
运行检查 ruff format main.py
之后如下图:
log = new_log(
tracker["ip_address"],
tracker["request_url"],
tracker["request_port"],
tracker["request_path"],
tracker["request_method"],
tracker["browser_type"],
tracker["operating_system"],
tracker["request_time"],
)
自动修复错误 (autofix)
Linter 扫描到问题之后,最好是能够自动修复错误,不仅省时也相当省力,Ruff 也支持 autofix 的功能,只要加上 参数就 --fix
能够启用自动修复
$ ruff check --fix test.py
配置规则
Ruff 总共支持三种设定文件:pyproject.toml
、ruff.toml
、.ruff.toml
。
如果不知道怎么开始,参考文件是最快上手的方式。 以下的范例与解说,我采用设定文件格式是 pyproject.toml
。
Ruff 因为功能众多,设定上较为复杂。所幸, 大部分时候,我们只需要设定一些基本的项目 。
基本设定
在 pyproject.toml
中,设置的 key 定是 [tool.xxx]
格式。
Linter 部分,一些基本的设定比如 line-length
和 Flake8 类似。其中 select
和没有列出的 ignore
相对重要。
Ruff 默认只会显示 E
和 F
系列的错误讯息(而 Flake8 还有 W
系列)。 想要增加或排除特定部分的错误讯息警示,就得透过 select
字段调整。比如:
[tool.ruff]
line-length = 100
target-version = "py310"
[tool.ruff.lint]
select = ["E", "F", "I", "UP"] # I 和 UP 是 isort 和 pyupgrade
[tool.ruff.format]
# 选项有 "single" 和 "double"
quote-style = "single"
# 启用 docstring 代码片段格式化
docstring-code-format = true
select
加上了 I
和 UP
。分别代表了 isort 和 pyupgrade。一旦开启了它们,Ruff 就会提示相关错误,并在有错误时自动修正。 (autofix 默认为打开)
因为开启了 UP
,所以必须设定 target-version
(这里为 py310
),意味着 Ruff 会将代码中旧的写法自动转换(autofix)为 Python 3.10 的写法。
pre-commit 设定
pre-commit 设定相对单纯,更细部的行为,hook 会自动读取配置文件中的内容。
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.4
hooks:
- id: ruff
args:
- --fix
- id: ruff-format