Black - 无妥协的Python代码格式化工具

项目标题与描述

Black是一个无妥协的Python代码格式化工具。通过自动格式化代码,Black帮助开发者节省时间,减少代码审查中的格式争议,并保持代码风格的一致性。Black的设计理念是"任何颜色都可以",意味着它不提供配置选项来调整格式化的细节,从而确保所有使用Black的项目代码风格统一。

状态徽章
许可证
PyPI版本
下载量
代码风格

功能特性

  • 无妥协的格式化: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智能小助手)
公众号二维码

posted @ 2025-07-12 22:02  qife  阅读(67)  评论(0)    收藏  举报