【问题标题】:Automatically disallowing large indentations自动禁止大缩进
【发布时间】:2021-08-09 15:09:11
【问题描述】:

在我们的代码库中,我经常发现按以下方式格式化的函数:

some_function_with_a_very_long_name(parameter_a,
                                    parameter_b,
                                    parameter_c)

这会将大量信息移到屏幕右侧,并且比更简洁的替代方案可读性差:

some_function_with_a_very_long_name(
    parameter_a,
    parameter_b,
    parameter_c,
)

这可以通过检查任何给定行中的缩进数最多比前一行大一个缩进级别来检测。

是否有任何 linting 规则(在 Flake8、SonarQube 或类似中)可用于自动检查这在我们的 CI/CD 管道中是否正确完成?

【问题讨论】:

  • black 自动包装参数,但我猜你更喜欢只检查缩进的东西?
  • 这不仅仅是一条规则,而且看起来很有希望。如果没有更多的最小解决方案,我可能最终会使用黑色!谢谢!

标签: python static-analysis


【解决方案1】:

这是我刚刚写的一个函数,它返回所有(应该是所有)块的列表,其中有像这里这样的过度缩进(也是代码行(从第 1 行开始)):

some_function_with_a_very_long_name(parameter_a,
                                    parameter_b,
                                    parameter_c)

然后您可以遍历该列表以打印出所有这些案例
代码:

def find_over_indentations(file_name, level_depth, search_possible=True):
    def count_spaces_before(lst):
        counter = 0
        for item in lst:
            if item == '':
                counter += 1
                counter = counter
            else:
                break
        return counter

    faulty_blocks = list()
    faulty_block = ''
    previous_line = ''
    caution = False
    previous_indentation_level = 0

    with open(file_name) as file:
        for index, line in enumerate(file):
            split_by_space = line.split(' ')
            spaces_before = count_spaces_before(split_by_space)
            current_indentation_level = spaces_before // level_depth
            possible_fault = spaces_before % level_depth if search_possible else 0
            if ((current_indentation_level - previous_indentation_level > 1 or possible_fault != 0)
                    and faulty_block == ''):
                caution = True
                faulty_block += str(index) + ' ' + previous_line
                faulty_block += str(index + 1) + ' ' + line
            elif caution and current_indentation_level == previous_indentation_level:
                faulty_block += str(index + 1) + ' ' + line
            else:
                if faulty_block != '':
                    faulty_blocks.append(faulty_block)
                    faulty_block = ''
                caution = False
            previous_indentation_level = current_indentation_level
            previous_line = line
    if faulty_block != '':
        faulty_blocks.append(faulty_block)

    return faulty_blocks


if __name__ == '__main__':
    over_indents = find_over_indentations('test.py', 4)
    for over_indented in over_indents:
        print(over_indented)

基本上,您可以只使用此代码(只需将文件名替换为您需要的任何文件),它应该打印出所有这些问题所在的行(例如,在上述情况下,它还将显示“起始”行这也将被打印:some_function_with_a_very_long_name(parameter_a,),也可以切换可能的故障(默认为 true),它基本上检查是否有超出级别深度的缩进,例如额外的一两个空格,级别深度参数是多深例如级别通常是 4 个空格(制表符)

EDIT1:第一个 if 语句有一个小问题,因为它运行 if 语句两次可能存在错误(超出缩进深度),所以我添加了一个条件,以便 if 语句仅在以下情况下运行faulty_block 没有附加任何内容。 (这也在当前引入了一个有趣的情况,它根据缩进级别正确格式化,但是如果此函数在此文件上运行,它将被附加到列表中,这就是为什么它显示行号和上一行以便人类可以去并手动检查它们,但他们不必查看整个文件)

【讨论】:

  • 编辑答案以包含更完整的代码
  • 也以防万一我只是想告诉您如果这解决了您的问题,请不要删除该问题,因为此答案可能会帮助未来的读者(也将其标记为已接受将有助于未来的读者,这将是可能的将其他问题标记为与此问题重复)
  • 感谢您的贡献。我宁愿不要在构建管道中引入更多自定义代码以避免必须维护它,但这确实可以做到。我不会删除问题,别担心!
猜你喜欢
  • 1970-01-01
  • 2011-07-21
  • 2010-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多