我继承了一些python 2.7代码,这些代码在每一行的开头都注释掉了代码段,这使我发疯。该代码分为多个文件,总行数超过5万行,因此,我正在寻找一种自动更正此问题的方法。并非所有注释都在各行的开头,但有些注释是。我尝试过reindent和autopep8,但是它们都不能解决此问题。这是一个示例:
def test_function():
a = 1
# There are comments that are not indented!
# Usually with commented out code like this:
# c = 5
# if c > a:
# a = c
b = 5
return a*b
print(test_function())
有时,即使缩进级别为4或5级,注释也位于行的开头。理想情况下,以上将转换为以下。请注意,这涉及到如何在代码行的注释之后调整和之前的空白,以使它们以应有的方式注释。那将是理想的,但我什至会更高兴让它只在开始时添加空白,而在评论后不进行调整,这可能会容易得多。
def test_function():
a = 1
# There are comments that are not indented!
# Usually with commented out code like this:
# c = 5
# if c > a:
# a = c
b = 5
return a*b
print(test_function())
在我自己尝试创建某些东西之前,有人知道是否已经有一些图书馆可以做到这一点?
答案 0 :(得分:0)
我整理了一些天真的awk
脚本,该脚本应该能够缩进您的评论:
#!/usr/bin/gawk -f
BEGIN{
last_indent=0
}
{
indent=match($0, /[^ ]/) - 1
if (indent < 0) indent = 0
comment=0
}
/^#/{
comment=1
if (last_indent > 0) {
indent_str = sprintf("%*s", last_indent, " ")
$0 = indent_str $0
}
}
{
print
if (length($0) && ! comment) last_indent=indent
}
运行它:
$ cat src.py | ./reindent.awk
(对于您的示例文件,它应该这样做)在输入的python文件中打印出与注释前面的当前块相对应的多余空格。
我已经考虑过您对注释中的代码的额外要求可以调整,但这是不平凡的,因为脚本实际上必须对其处理的内容有相当的了解。
不用说,在大多数情况下,应该删除评论并将其保留不是一个整洁的做法,至少由于我们拥有源代码的版本控制系统(大约70年代初期)。
在一个简单的例子中,这也许甚至可以成功缩进注释中的代码:
#!/usr/bin/gawk -f
BEGIN{
last_indent=0
commented_code_indent = 0
}
{
indent=match($0, /[^ ]/) - 1
if (indent < 0) indent = 0
comment=0
}
/^#/{
comment=1
if (last_indent > 0) {
indent_str = sprintf("%*s", last_indent, " ")
stripped = length($0)
sub(/# +/, "# ")
stripped -= length($0)
if (stripped > 0 && ! commented_code_indent) commented_code_indent = stripped
if (commented_code_indent > 0) {
indent_in_comment = stripped - commented_code_indent
if (indent_in_comment > 0) {
comment_indent_str = sprintf("%*s", indent_in_comment, " ")
sub(/# /, "# " comment_indent_str)
}
}
$0 = indent_str $0
}
}
{
print
if (length($0) && ! comment) last_indent=indent
if (! comment) commented_code_indent = 0
}
是的,现在来看,本来可能是更简单的选择,然后是awk。 :)
答案 1 :(得分:0)
此缩进以#
开头的行与下一个非注释行的缩进级别相同:
import sys
def remove_excess_space(comments):
"""Remove excess whitespace after #"""
excess = 0
for line in comments:
stripped = line.lstrip('#').lstrip()
if excess == 0:
excess = len(line) - len(stripped) - len('# ')
if excess > 0:
line = '#{}'.format(line[1 + excess:])
yield line
def fix(filename):
indentation = 0
comments = []
with open(filename, 'r') as f:
for line in f:
if line.startswith('#'):
comments.append(line)
else:
stripped = line.lstrip()
if stripped and not stripped.startswith('#'):
# I'm assuming indentation is done with spaces, not tabs
indentation = len(line) - len(stripped)
if comments:
# indent the comments using the same indenation as the next non-comment line
print(''.join(['{}{}'.format(' '*indentation, line)
for line in remove_excess_space(comments)]), end='')
comments = []
print(line, end='')
if __name__ == '__main__':
filename = sys.argv[1]
fix(filename)
如果我们调用此indent_comments.py
然后运行:
indent_comments.py /path/to/script.py
打印
def test_function():
a = 1
# There are comments that are not indented!
# Usually with commented out code like this:
# c = 5
# if c > a:
# a = c
b = 5
return a*b
print(test_function())
请注意,在某些极端情况下,此脚本会出错。例如,
并非以#
开头的每一行都必须是注释:
print('''\
# This is not
a comment
''')
将成为
print('''\
# This is not
a comment
''')