Black - 无妥协的Python代码格式化工具
项目标题与描述
Black是一个无妥协的Python代码格式化工具。通过自动格式化代码,Black帮助开发者节省时间,减少代码审查中的格式争议,并保持代码风格的一致性。Black的设计理念是"任何颜色都可以",意味着它不提供配置选项来调整格式化的细节,从而确保所有使用Black的项目代码风格统一。
功能特性
- 无妥协的格式化:Black提供统一的代码风格,不接受配置选项来调整格式化的细节
- 快速执行:优化过的代码格式化速度,适合大型项目
- 确定性输出:相同的代码总是产生相同的格式化结果
- 最小化差异:格式化后的代码产生最小的差异,便于代码审查
- 现代Python支持:全面支持Python 3.7+的所有语法特性
- 多种集成方式:
- 命令行工具
- 预提交钩子(pre-commit)
- 编辑器插件
- 作为库使用
- Jupyter Notebook支持:可以格式化Jupyter Notebook中的代码单元格
- 类型注释支持:正确处理类型注释和类型提示
- 字符串规范化:可选地统一字符串引号风格
安装指南
基本安装
使用pip安装最新稳定版:
pip install black
安装可选依赖
要支持Jupyter Notebook格式化:
pip install "black[jupyter]"
通过conda安装
conda install -c conda-forge black
系统要求
- Python 3.7或更高版本
- 对于Jupyter Notebook支持,需要安装额外依赖
使用说明
基本使用
格式化单个文件:
black filename.py
格式化目录下的所有Python文件:
black path/to/directory/
常用选项
检查文件是否需要格式化而不实际修改:
black --check filename.py
设置不同的行长度限制(默认为88):
black --line-length 100 filename.py
代码示例
格式化前:
def very_important_function(template: str,*variables,file: os.PathLike,engine: str,header: bool=True,debug: bool=False):
"""应用变量到模板并写入文件"""
with open(file, 'w') as f:
...
格式化后:
def very_important_function(
template: str,
*variables,
file: os.PathLike,
engine: str,
header: bool = True,
debug: bool = False,
):
"""应用变量到模板并写入文件"""
with open(file, "w") as f:
...
核心代码
主要格式化逻辑
def format_str(src_contents: str, mode: FileMode) -> str:
"""格式化字符串形式的Python代码"""
try:
src_node = lib2to3_parse(src_contents)
except ParseError as pe:
raise InvalidInput(str(pe)) from pe
dst_contents = []
lines = LineGenerator(mode=mode)
elt = EmptyLineTracker(mode=mode)
split_line_features = {
feature
for feature in {Feature.TRAILING_COMMA_IN_CALL, Feature.TRAILING_COMMA_IN_DEF}
if supports_feature(mode.target_versions, feature)
}
for line in transform_line(src_node, mode=mode):
dst_contents.append(line_to_string(line))
return "".join(dst_contents)
字符串规范化处理
def normalize_string_quotes(leaf: Leaf) -> None:
"""将字符串中的所有引号规范化为双引号"""
value = leaf.value
if value.startswith(("'", '"')) and len(value) > 1:
prefix = get_string_prefix(value)
unescaped_newlines = False
if "r" not in prefix.lower():
unescaped_newlines = len(value) - len(value.replace("\\\n", "")) > 0
if not unescaped_newlines:
if value.startswith("'''") or value.startswith('"""'):
new_prefix = prefix + '"""'
new_value = new_prefix + eval(value[len(prefix):]) + '"""'
else:
new_prefix = prefix + '"'
new_value = new_prefix + eval(value[len(prefix):]) + '"'
leaf.value = new_value
类型注释处理
def format_type_comment(node: Node, mode: Mode) -> str:
"""格式化类型注释"""
type_comment = node.type_comment
if not type_comment:
return ""
try:
parsed = lib2to3_parse(type_comment)
except ParseError:
return type_comment
formatted = format_str(type_comment, mode=mode)
return formatted.strip()
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)
公众号二维码


浙公网安备 33010602011771号