Python Black 使用指南 #

什么是 Black? #

Black 是一个用于 Python 代码的自动格式化工具,以 “不妥协的代码格式化” 理念著称。它通过移除开发者在代码风格上的决策负担,帮助团队实现代码风格的完全统一。

Black 的主要特点 #

  • 零配置:默认设置已经符合大多数项目需求
  • 可预测:相同的输入总是产生相同的输出
  • 快速:处理大型代码库也能保持高效
  • 广泛支持:兼容 Python 3.6+,支持各种常见的 Python 语法特性
  • IDE 集成:可与主流 IDE 和编辑器无缝集成

安装 Black #

基本安装 #

使用 pip 安装 Black:

bash
pip install black

安装特定版本 #

bash
pip install black==23.3.0

安装开发版本 #

bash
pip install git+https://github.com/psf/black.git

检查安装 #

验证 Black 是否成功安装:

bash
black --version

基本使用 #

格式化单个文件 #

bash
black my_script.py

格式化多个文件 #

bash
black file1.py file2.py file3.py

格式化目录 #

格式化当前目录下的所有 Python 文件:

bash
black .

格式化指定目录下的所有 Python 文件:

bash
black my_project/

递归格式化 #

递归格式化目录及其子目录中的所有 Python 文件:

bash
black my_project/ --recursive
# 或
black my_project/ -r

配置选项 #

行长度设置 #

默认行长度为 88 个字符,可自定义:

bash
black --line-length 100 my_script.py

检查模式 #

检查代码是否符合 Black 格式,但不实际修改文件:

bash
black --check my_script.py

不包含某些文件 #

使用 .gitignore.blackignore 文件指定要忽略的文件,或直接在命令行中指定:

bash
black --exclude '/(git|venv|env|build|dist)/' .

静默模式 #

减少输出信息:

bash
black --quiet my_script.py
# 或
black -q my_script.py

详细模式 #

显示更多信息:

bash
black --verbose my_script.py
# 或
black -v my_script.py

版本控制集成 #

将 Black 与 Git 钩子结合使用,确保提交的代码都经过格式化:

  1. 安装 pre-commit:

    bash
    pip install pre-commit
    
  2. 在项目根目录创建 .pre-commit-config.yaml 文件:

    yaml
    repos:
    -   repo: https://github.com/psf/black
        rev: 23.3.0
        hooks:
        -   id: black
    
  3. 安装钩子:

    bash
    pre-commit install
    

高级用法 #

使用 Black 配置文件 #

创建 pyproject.toml 文件并添加 Black 配置:

toml
[tool.black]
line-length = 100
target-version = ['py38']
include = '\.pyi?
exclude = '''
/(\.git
 |\.venv
 |env
 |build
 |dist
)/
'''

格式化 Jupyter Notebook #

Black 支持格式化 Jupyter Notebook 文件(.ipynb):

bash
black my_notebook.ipynb

与其他工具结合使用 #

与 Flake8 结合 #

安装 flake8-black 插件:

bash
pip install flake8-black

然后正常使用 flake8:

bash
flake8 my_script.py

与 isort 结合 #

安装 isort 并配置与 Black 兼容:

bash
pip install isort

pyproject.toml 中添加配置:

toml
[tool.isort]
profile = "black"

命令行参数速查 #

bash
black [OPTIONS] [SRC]...

选项:
  -l, --line-length INTEGER       行长度限制 [默认: 88]
  -t, --target-version [py36|py37|py38|py39|py310|py311]  Python 目标版本
  --pyi                           格式化 .pyi 文件
  --ipynb                         格式化 .ipynb 文件
  -c, --code TEXT                 格式化指定的代码字符串
  -S, --skip-string-normalization  跳过字符串规范化
  -C, --skip-magic-trailing-comma  跳过魔法尾随逗号
  --check                         检查模式,不实际修改文件
  --diff                          显示修改前后的差异
  -q, --quiet                     减少输出信息
  -v, --verbose                   增加输出信息
  --version                       显示版本信息
  --help                          显示帮助信息

Black 工作原理 #

Black 采用一种 “不妥协” 的格式化策略:

  1. 解析代码:使用 lib2to3 解析器将 Python 代码转换为抽象语法树 (AST)
  2. 重新生成代码:从 AST 重新生成代码,应用 Black 的格式化规则
  3. 保持语义:确保格式化后的代码与原始代码具有完全相同的语义
  4. 统一风格:移除所有原始的格式化信息,应用一致的风格

Black 的格式化规则 #

  • 缩进:使用 4 个空格,不使用制表符
  • 引号:默认使用双引号,自动规范化字符串引号
  • 行长度:默认 88 个字符,基于经验优化的折行阈值
  • 空行:在函数、类定义之间使用两个空行,在方法之间使用一个空行
  • 逗号:自动添加尾随逗号以提高 Git 差异可读性
  • 括号:在多行表达式中使用括号换行

常见问题与解决方案 #

如何忽略特定代码段不被 Black 格式化? #

使用 # fmt: off# fmt: on 注释:

python
# fmt: off
# 这段代码不会被 Black 格式化
def messy_function(argument1, argument2, argument3,
                  argument4):
    return argument1 + argument2 * argument3 - argument4
# fmt: on

# 这段代码会被 Black 格式化
def clean_function(argument1, argument2, argument3, argument4):
    return argument1 + argument2 * argument3 - argument4

Black 格式化后导致代码可读性下降怎么办? #

虽然 Black 自称 “不妥协”,但在某些情况下可以通过调整代码结构来改善可读性:

  1. 将长表达式分解为多个变量
  2. 使用括号明确分组
  3. 考虑重构复杂函数

如何在团队中引入 Black? #

  1. 渐进式引入:先在非关键项目或新项目中试用
  2. 一次大规模格式化:使用 black . 一次性格式化整个代码库
  3. 提交格式化结果:将格式化后的代码作为单独的提交
  4. 更新开发流程:将 Black 集成到 CI/CD 管道和 Git 钩子中
  5. 培训团队:确保所有团队成员了解 Black 的使用方法和理念

最佳实践 #

项目级配置 #

  • 在项目根目录添加 pyproject.toml 文件统一配置 Black
  • 指定明确的 Python 目标版本
  • 定义清晰的包含和排除规则

开发流程集成 #

  • 将 Black 集成到 IDE 或编辑器中
  • 使用 pre-commit 钩子确保提交前格式化
  • 在 CI/CD 管道中添加 Black 检查

团队协作 #

  • 团队达成一致,接受 Black 的格式化结果
  • 避免在代码审查中讨论 Black 已经处理的格式问题
  • 将代码风格的讨论集中在 Black 无法处理的问题上

与其他格式化工具的比较 #

工具 特点 适用场景
Black 零配置、不妥协、快速 需要严格统一风格的团队
autopep8 基于 PEP 8、可配置 已有代码库的渐进式格式化
yapf 高度可配置、多种风格 需要自定义格式规则的项目

总结 #

Black 是一个强大的 Python 代码格式化工具,通过移除代码风格决策,帮助团队实现代码风格的完全统一。它的零配置设计和快速性能使其成为现代 Python 开发流程中的重要工具。

无论是个人项目还是大型团队,Black 都能显著提高开发效率,减少代码审查中的风格讨论,让开发者专注于真正重要的代码逻辑。

进一步阅读 #