为何添加注释后Black对Python代码的格式化结果不同?
为何添加一行注释后Black格式化结果出现差异?
我的目标并非保留代码原有格式或禁用Black包格式化功能,而是想了解为何仅添加一行注释,两段代码的Black格式化结果就出现差异。我认为在配置不变的情况下,逻辑相同的代码应得到一致的格式化结果。
示例1
原Python代码
def long_long_long_long_long_long_long_long_long_long_long_long_func(arg: list): ... long_long_long_long_long_long_long_long_long_long_long_name = ( long_long_long_long_long_long_long_long_long_long_long_long_func( arg=[ "long_long_long_long_long_long_long_long_long_long_long_string", "long_long_long_long_long_long_long_long_long_long_long_string", ] ) )
经Black格式化后无变化,符合预期。
示例2
原Python代码
def long_long_long_long_long_long_long_long_long_long_long_long_func(arg: list): ... long_long_long_long_long_long_long_long_long_long_long_name = ( long_long_long_long_long_long_long_long_long_long_long_long_func( arg=[ "long_long_long_long_long_long_long_long_long_long_long_string", # a comment "long_long_long_long_long_long_long_long_long_long_long_string", ] ) )
格式化后结果(不符合预期)
def long_long_long_long_long_long_long_long_long_long_long_long_func(arg: list): ... long_long_long_long_long_long_long_long_long_long_long_name = long_long_long_long_long_long_long_long_long_long_long_long_func( arg=[ "long_long_long_long_long_long_long_long_long_long_long_string", # a comment "long_long_long_long_long_long_long_long_long_long_long_string", ] )
环境信息
- black, 24.8.0 (compiled: yes)
- Python (CPython) 3.9.19
- macOS Sonoma 14.5
已尝试操作
- 简化示例代码以复现问题
- 查阅Black文档中换行、最大长度相关内容,未找到解释
- 在Stack Overflow和Google搜索相关问题,未找到有效说明
问题解答
这是Black的注释感知换行逻辑导致的差异。Black在计算行长和决定是否保留括号换行时,会将注释纳入整体结构的考量:
- 示例1中,函数调用的嵌套结构(带括号的赋值)整体的视觉长度和结构复杂度符合Black保留换行的阈值,所以维持原有括号换行格式。
- 示例2中添加的注释会改变Black对列表内部结构的判断——注释被视为列表项的一部分,使得Black认为整个函数调用的结构紧凑性发生变化,进而调整外层赋值格式:去掉赋值右侧的括号,将函数名直接放在等号后,仅保留函数参数内部的换行。
本质上,Black的格式化逻辑并非完全只看代码的逻辑等价性,而是会结合注释、空白等非逻辑元素调整排版,以保证注释与相邻代码的可读性,这就导致了逻辑相同但带注释的代码出现不同格式化结果。
内容的提问来源于stack exchange,提问作者Issac
相关产品推荐
相关产品推荐

