Python 源代码缩进格式化工具

前言

昨天在跟小伙伴聊天,当他谈起自己正在做的项目时,一脸愁容。

他吐槽道:“该项目的 Python 代码库由多个人共同维护。由于每个人使用的编辑器不同,每个人的编码风格也不同,最终导致了

代码的缩进千奇百怪:有缩进 2 个空格的,有缩进 4 个空格的,有缩进 8 个空格,有缩进一个 Tab 的,更有缩进随机数量空

的。导致代码的可读性非常差。“

在这里插入图片描述

小伙伴还说:“这种长短不一的代码看着非常难受,我就手动将它们全部改成标准四空格缩进了。也考虑过使用自动化脚本,但一

时间没什么思路,就搁置了。”

这反映出一个问题:不同长度的缩进,虽不影响代码解释,但可读性非常差,一律使用标准的四空格缩进是个不错的主意。于

是,我便尝试写一个简单的脚本工具,来解决这个实际问题。

经过简单分析,确定如下思路:

•由于 Python 的缩进是按照层级进行的,只要下一层缩进比上一层更深,且同一层级的所有代码缩进相同即可;

•可以逐行对源文件进行处理,对每一行源代码,统计行前空格字符数量,确定该行代码的缩进层级;

•每嵌套一层缩进,将空格数量增加四位,并记录当前缩进层级;

•当发现当前行的缩进层级小于上一行代码,则表示当前行已跳出一层或所层嵌套,对记录层级的列表由后至前进行搜索,找到当

前行代码对应的缩进层级;

在这里插入图片描述

•对于当前行代码,根据其缩进层级,对其行首添加相应数量的空格。

为了统计每一行源代码前的空格数量,我们使用 行的原始长度 - 删除行左侧空白后的长度 表示。

示例代码如下:

Python学习交流Q群:906715085####
 1file_input = 'source.py'  # file to format
 2file_output = 'dest.py'   # formated file
 3
 4fin = open(file_input, 'r')
 5fout = open(file_output, 'w')
 6
 7space = 0
 8indent_lists = [0]
 9
10for line in fin:
11    # blank line just output
12    if len(line.lstrip()) == 0:
13        fout.write(line)
14        continue
15    # calc curret indent
16    indent = len(line) - len(line.lstrip())
17    # inc space when bigger indent
18    if indent > indent_lists[-1]:
19        indent_lists.append(indent)
20        space = space + 4
21    # dec space when smaller indent
22    while indent < indent_lists[-1]:
23        indent_lists.pop()
24        space = space - 4
25    # format the line
26    line = ' ' * space + line.lstrip()
27    fout.write(line)
28
29fin.close()
30fout.close()

下面我们进行简单的测试。

待格式化的源文件:
1#!/usr/bin/python
2# -*- coding: UTF-8 -*-
3
4for num in range(1, 10):
5  if num % 2 == 0:
6          print(str(num) + ' is even')
7  else:
8      print(str(num) + ' is odd')

在这里插入图片描述

可以看到:line5 缩进了 2 个空格,line6 缩进了 8 个空格,line8缩进了 4 个空格。看起来非常杂乱。

使用本脚本格式化后的源文件:

1#!/usr/bin/python
2# -*- coding: UTF-8 -*-
3
4for num in range(1, 10):
5    if num % 2 == 0:
6        print(str(num) + ' is even')
7    else:
8        print(str(num) + ' is odd')

可以看到,执行脚本后,所有的缩进都变成了 4 个空格。舒服了…

随后小伙伴又提出:这个脚本每次只能处理一个文件,能不能批量处理呢?当然可以啦!只要对本脚本进行简单的封装,即可实

现多文件、多目录处理啦:

 1def format_file(file_input, file_output):
 2    fin = open(file_input, 'r')
 3    fout = open(file_output, 'w')
 4
 5    space = 0
 6    indent_lists = [0]
 7
 8    for line in fin:
 9        # blank line just output
10        if len(line.lstrip()) == 0:
11            fout.write(line)
12            continue
13        # calc curret indent
14        indent = len(line) - len(line.lstrip())
15        # inc space when bigger indent
16        if indent > indent_lists[-1]:
17            indent_lists.append(indent)
18            space = space + 4
19        # dec space when smaller indent
20        while indent < indent_lists[-1]:
21            indent_lists.pop()
22            space = space - 4
23        # format the line
24        line = ' ' * space + line.lstrip()
25        fout.write(line)
26
27    fin.close()
28    fout.close()
29
30files_to_format = 3
31file_input_lists = ['1.py', '2.py', '3.py']       # file lists to format
32file_output_lists = ['11.py', '22.py', '33.py']   # formated file lists
33
34for i in range(files_to_format):
35    format_file(file_input_lists[i], file_output_lists[i])

上面代码只是一个简单的做法,当然我们可以根据目录或者更多规则进行文件格式化,本例仅做抛砖引玉之意。

今天的分享到这里就结束了,下一章见啦!!!

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/xff123456_/article/details/124513054