Black 代码格式化器完全指南从安装配置到源码级风格流水线解析【免费下载链接】blackThe uncompromising Python code formatter项目地址: https://gitcode.com/GitHub_Trending/bl/blackBlackThe Uncompromising Code Formatter不妥协的 Python 代码格式化器是 PSF 出品的 Python 自动格式化工具。本文以仓库根目录的 README.md 为主线覆盖其设计哲学、安装与用法、风格规则与务实例外、pyproject.toml配置方式并结合 src/black/init.py、src/black/mode.py 等源码深入讲解一次格式化背后的实际执行流水线。读完后你可以直接在生产项目中落地 Black并理解它的每个默认值从何而来。一、Black 是什么一场关于格式控制权的交易README 的开篇就点明了 Black 的核心主张Any color you like.喜欢什么颜色都行。Black是不妥协的 Python 代码格式化器。使用它意味着你放弃对手工格式细节minutiae的控制权作为交换Black 给你速度、确定性以及免于被pycodestyle反复唠叨格式问题的自由从而把时间和精力留给更重要的事情。它的三个关键特性直接写在 README 中跨项目一致性被 Black 格式化过的代码在任何项目里读起来都是一样的。格式在一段时间后变得透明你可以专注于代码内容本身更小的 diffBlack 以产生尽可能小的 diff 为目标从而让代码审查code review更快确定性同样的输入永远得到同样的输出风格争议在团队内被终结。源码印证88 列与只认 .py的默认值Black 的默认行为在源码中集中定义于 src/black/const.pyDEFAULT_LINE_LENGTH 88 DEFAULT_EXCLUDES r/(\.direnv|\.eggs|\.git|\.hg|\.ipynb_checkpoints|\.mypy_cache|\.nox|\.pytest_cache|\.ruff_cache|\.tox|\.svn|\.venv|\.vscode|__pypackages__|_build|buck-out|build|dist|venv)/ DEFAULT_INCLUDES r(\.pyi?|\.ipynb)$这解释了两件事为什么 Black 默认行宽是 88 而不是 PEP 8 的 7988 是为了兼容 80 列宽编辑器下的 88 字符缓冲区以及为什么直接对目录运行black .时.git、.venv、build、虚拟环境等目录会被自动跳过、只有.py/.pyi/.ipynb文件会被处理——这些正是 README 强调的sensible defaults合理默认值的源码出处。二、安装与基本用法2.1 安装Black 运行需要Python 3.10见 pyproject.toml 中的requires-python 3.10。安装方式如下pip install black如果需要格式化 Jupyter Notebook需安装 jupyter 扩展依赖对应 pyproject.toml 中[project.optional-dependencies]的jupyter [ipython7.8.0, tokenize-rt3.2.0]pip install black[jupyter]此外如果不想安装 Python 环境也可以从最新的 GitHub release 下载 PyInstaller 打包的独立可执行文件README 中给出仓库的 pyproject.toml 中[tool.cibuildwheel]段落即为这些跨平台二进制文件的构建配置覆盖 CPython 3.10 的 Linux/Windows/macOS 64 位平台。2.2 三种调用方式方式一直接运行脚本最快black {source_file_or_directory}方式二作为 Python 包运行脚本不可用时python -m black {source_file_or_directory}方式三格式化代码字符串而不触碰文件$ black --code print ( hello, world ) print(hello, world)命令行参数入口由 pyproject.toml 中的black black:patched_main[project.scripts]注册主入口patched_main与main均定义在 src/black/init.py。2.3 Black 是守规矩的 Unix 工具配合仓库文档 docs/usage_and_configuration/the_basics.mdREADME 中直接跑就得到合理结果的承诺背后有一套明确约定找不到任何可格式化源码时什么都不做文件名用-表示从标准输入读、写标准输出所有面向用户的信息只输出到stderr退出码为 0除非发生内部错误或某个 CLI 选项要求非零退出这对 CI 集成很重要--check模式会因存在未格式化代码而返回非零。2.4 安全网AST 校验与--fastREADME 特别提到一个安全机制作为会拖慢处理的安全措施Black会检查重新格式化后的代码仍然能产生与原始代码在语义上等效的 AST详见文档中 Pragmatism 一节的 AST Before and After Formatting 部分。如果你对自己的代码有信心、想换取速度可以使用black --fast {source}从源码结构看这个校验发生在format_file_contents/format_file_in_placesrc/black/init.py 起中格式化前对源码做一次ast.dump格式化后再做一次并比较不一致即报错并保留原文件——这也是仓库 CHANGES.md 中大量fix unparseable output / failed Blacks own AST safety check条目存在的原因Black 把输出必须可解析且语义等价当作硬性验收标准。三、Black 代码风格受限的配置 有限度量的务实3.1 风格总则README 对风格的表述可以概括为四条PEP 8 兼容Black 是 PEP 8 兼容的、有主见的opinionated格式化器整文件就地重写_Black_ reformats entire files in place配置项刻意受限风格配置选项被刻意限制、极少新增不参考原有格式它基本不考虑你之前的排版少数例外见务实一节最典型的是 magic trailing comma。这套一行一个表达式、超出行宽就沿括号逐层展开的具体排版规则在仓库文档 docs/the_black_code_style/current_style.md 中有完整示例例如短表达式会被合并回一行# in: j [1, 2, 3] # out: j [1, 2, 3]而超长的函数签名会被逐参数展开闭括号回退缩进且补上尾随逗号def very_important_function( template: str, *variables, file: os.PathLike, engine: str, header: bool True, debug: bool False, ): ...3.2 稳定性策略与务实PragmatismREADME 明确风格变更受Stability Policy约束——Black 已趋于稳定不应预期未来出现大规模格式变化风格变更主要是对 bug 报告的响应和新 Python 语法的适配。它同时警告提交 issue 之前请先阅读 Current style 与 Future style 两份文档看似 bug 的行为可能是有意设计。Pragmatism务实一节说明Black 早期版本在某些方面是绝对主义的追随其最初作者的风格偏好这在用户很少时让实现更简单作为成熟工具Black 现在会对其一般规则做有限的例外处理。这些例外在文档中有专门章节The Black code style: Pragmatism阅读它同样应在提 issue 之前进行。3.3 源码印证一次格式化到底发生了什么理解整文件重写 确定性最直观的方式是看核心流水线。入口函数format_str定义在 src/black/init.py其文档字符串本身就给出了标准用法import black print(black.format_str(def f(arg:str)-None:..., modeblack.Mode())) # 输出: # def f(arg: str ) - None: # ...format_str内部委托给_format_str_oncesrc/black/init.py完整调用链为decode_bytes用tokenize.detect_encoding检测文件头声明的编码识别 LF/CRLF/CR 换行并在输出时还原避免 Windows 换行被无谓改写lib2to3_parse用仓库内置的 src/blib2to3lib2to3 的分叉构建语法树这是 Black 不依赖 CPython 解析器版本、从而能解析未来语法的关键目标版本检测若用户未通过-t指定则调用detect_target_versions依据from __future__导入与 src/black/init.py 中get_features_used识别到的语言特性f-string、下划线数字字面量、海象运算符、match 语句、except*、可变参数泛型、懒导入等见Feature枚举与VERSION_TO_FEATURES映射定义在 src/black/mode.py推断语法兼容的版本集LineGenerator遍历语法树生成候选逻辑行src/black/linegen.pyEmptyLineTracker维护函数/类之间的空行规则transform_line按Mode中的line_length对每行执行括号爆炸bracket splitting等变换强制第二遍format_str中有一段注释直白的Admittedly ugly逻辑——如果第一遍产生了变化就用第一遍的输出再格式化一次。原因是可选尾随逗号在第二遍会变成强制尾随逗号进而与可选括号产生交互必须跑两遍才能收敛。这段源码是理解Black 输出是确定的固定点的最直接证据。Mode数据类src/black/mode.py是全部风格参数的载体dataclass class Mode: line_length: int DEFAULT_LINE_LENGTH # 默认 88 string_normalization: bool True # 默认统一双引号 ... preview: bool False # 预览风格开关这解释了 README风格配置选项刻意受限的由来——用户可调的旋钮主要就是line_length、string_normalization对应 CLI 的-l、-S与少量开关而非一份任意风格表。四、配置pyproject.toml是最主要的面板4.1 README 的原文结论Black可以从pyproject.toml读取命令行选项的项目级默认值这在为项目指定自定义的--include和--exclude/--force-exclude/--extend-exclude模式时特别有用详见 The basics: Configuration via a file 与 Usage and Configuration。README 还给出了官方 Pro-tip如果你在想我到底需不需要配置什么——答案是不需要。Black 的全部价值就在于合理默认值应用这些默认值你的代码就能与众多其他 Black 项目保持一致。4.2 一份可复制的真实配置Black 项目自用配置本仓库的 pyproject.toml 就是一份被 Black 官方注释过的配置范例可以直接作为模板# NOTE: you have to use single-quoted strings in TOML for regular # expressions. Its the equivalent of r-strings in Python. # Multiline strings are treated as verbose regular expressions by Black. # Use [ ] to denote a significant space character. [tool.black] line-length 88 target-version [py310] include \.pyi?$ extend-exclude /( # The following are specific to Black, you probably dont want those. tests/data/ | profiling/ ) # We use the unstable style for formatting Black itself. If you # want bug-free formatting, you should keep this off. unstable true几个要点TOML 正则有讲究正则必须用单引号字符串等价 Python 的 raw string多行字符串按verbose 正则解析[ ]表示显著空格——这正是extend-exclude里那段/( ... | ... )能写多行的原因include/extend-exclude分别对应 CLI 的同名选项用于覆盖 src/black/const.py 中的DEFAULT_INCLUDES/DEFAULT_EXCLUDESforce-exclude则连显式传入的路径也跳过适合排除第三方生成的目录target-version-t选项的文件版如target-version [py311, py312, py313]。它决定 Black 用什么语法解析代码、以及风格细节——例如只有当所有目标版本 ≥ py35 时Black 才会在f(a, *args)的*args后加尾随逗号docs/usage_and_configuration/the_basics.md 中给出了 py34/py35 的对比示例unstable true仅 Black 项目自身使用不稳定的预览风格普通项目若追求无 bug 的稳定格式应保持该标志关闭。对应源码中Mode的 preview 语义unstable 模式启用全部预览特性见 src/black/mode.py 中__contains__的实现注释。4.3 其他常用开关速查与 README 承诺的有限旋钮一致以下选项在 docs/usage_and_configuration/the_basics.md 中有完整说明均可同时以 CLI 或pyproject.toml形式配置选项作用-h, --help显示全部命令行选项-c, --code格式化传入的代码字符串-l, --line-length行宽默认 88-t, --target-version目标 Python 版本可多次给出--pyi/--ipynb强制按 stub / Notebook 处理输入管道输入场景-x, --skip-source-first-line跳过源码第一行-S, --skip-string-normalization保留字符串原样默认统一为双引号并规范化前缀-C, --skip-magic-trailing-comma忽略魔法尾随逗号默认会把你已有的尾随逗号当作请保持逐行展开的信号--preview启用下一大版本可能并入主功能、但可能有破坏性的风格变更--fast关闭 AST 前后比对安全校验换取速度--line-ranges只格式化指定行范围配合lines参数走 src/black/init.py 的sanitized_lines/adjusted_lines路径五、跳过格式化的三种注释指令虽然 README 正文未展开但作为以指定文档为主体、文档生态为辅佐的一环docs/usage_and_configuration/the_basics.md 定义了与放弃格式控制权直接对冲的逃生舱属于 README 承诺的基本用法范畴# fmt: skip跳过该行可与其他 pragma 混排# fmt: skip # pylint # noqa或分号列表形式# fmt: off/# fmt: on关闭/开启区间格式化两者必须处于同一缩进层级、同一代码块内兼容 YAPF 的# yapf: disable/enable块注释。六、社区采用与口碑README 的 Used by 一节列出了信任 Black 的知名开源项目pytest、tox、Pyramid、Django、Django Channels、Hypothesis、attrs、SQLAlchemy、Poetry、PyPA 系列应用Warehouse、Bandersnatch、Pipenv、virtualenv、pandas、Pillow、Twisted、LocalStack、Datadog Agent 全部集成、Home Assistant、Zulip、Kedro、OpenOA、FLORIS、ORBIT、WOMBAT 等以及使用它的组织Dropbox、KeepTruckin、Lyft、Mozilla、Quora、Duolingo、QuantumBlack、Tesla、Archer Aviation。README 同时收录了几位知名开发者的评价Testimonials其中 SQLAlchemy 作者 Mike Bayer 称其为整个编程生涯中带来的生产力提升最大的单一工具重构时的击键量降到原来的约 1%attrs 作者、Twisted 核心开发者 Hynek Schlawack 写道一个不烂的自动格式化器就是我全部的圣诞愿望requests 作者 Kenneth Reitz 则说它大幅改善了我们代码的格式化。测试与 CI 基础设施README 还提到 Black 拥有全面的测试套件、高效的并行测试以及自研的并行 CI 运行器仓库中 tests/test_black.py、tests/data/cases/ 下数百个输入/输出成对的用例文件如 tests/data/cases/comments.py、tests/data/cases/torture.py就是稳定性承诺的具体载体——每个历史 bug 修复都沉淀为一个回归用例。七、展示你的风格README 徽章在自己的项目 README 中声明使用了 Black是 README 给出的官方做法。Markdown 形式[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)RST 形式用于 README.rst.. image:: https://img.shields.io/badge/code%20style-black-000000.svg :target: https://github.com/psf/black八、许可、贡献与周边文档LicenseMIT见 LICENSEChange log更新日志较长独立存放于 CHANGES.md当前共 2000 余行按 Stable style / Preview style 等分类记录每次风格与行为变更Authors作者列表同样独立存放见 AUTHORS.mdContributing贡献入门见 docs/contributing/the_basics.md贡献流程见 docs/contributing/index.mdCode of Conduct遵循 Python 社区行为准则README 结尾还按项目幽默传统补了一句如果实在需要打某人请边跳舞边用鱼打。九、总结为什么这套设计值得借鉴从 README.md 到源码Black 的工程决策可以浓缩为三点默认值即产品88 列行宽src/black/const.py、自动排除虚拟环境与构建目录、按语法特性自动探测目标版本src/black/mode.py 的VERSION_TO_FEATURES让零配置成为真实可用的状态而非营销话术确定性与安全性双保险两遍格式化收敛src/black/init.py保证固定点输出AST 前后比对保证输出可解析、语义等价--fast留给愿意自己承担风险的场景变更治理稳定性策略 按 Stable/Preview 双通道发布风格变更CHANGES.md配合# fmt: skip/off逃生舱把工具替你格式化与必要时你说了算的边界划得清清楚楚。【免费下载链接】blackThe uncompromising Python code formatter项目地址: https://gitcode.com/GitHub_Trending/bl/black创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考