如何在Python中计算代码行数,排除注释和文档字符串?

21 投票
4 回答
20411 浏览
提问于 2025-04-17 12:00

我想尽可能准确地统计一个多文件的Python项目中的代码行数,但不想把注释、文档字符串和空行算进去。

我最开始尝试使用cloc,这是一个可以在Debian系统上安装的工具。不过,cloc之前把大多数文档字符串当作代码来处理——尽管它们其实是注释。(更新:现在的cloc版本已经改变了,它把Python的文档字符串当作注释处理了。)

我注意到下面有些评论说,文档字符串应该算在总行数里,因为它们可能会影响代码在运行时的行为,因此算作程序的一部分。不过,这种情况我觉得很少见。大多数时候,文档字符串就像注释一样。具体来说,我知道我想要测量的所有代码都是这样。所以我想把它们从我的行数统计中排除掉。

4 个回答

7

在Python中,注释行可以是代码行。比如你可以看看doctest这个例子。

而且,你会发现很难找到一个合理可靠的方法来判断像这样的情况是注释还是代码:

foo = ('spam', 
       '''eggs
          eggs
          eggs'''
       '''more spam''',
       'spam')

我觉得把注释行也算上,大多数程序员都会同意,这也是衡量你想要测量的内容的一个好方法。

8

Tahar 不会把文档字符串算在内。下面是它的 count_loc 函数:

def count_loc(lines):
    nb_lines  = 0
    docstring = False
    for line in lines:
        line = line.strip()

        if line == "" \
           or line.startswith("#") \
           or docstring and not (line.startswith('"""') or line.startswith("'''"))\
           or (line.startswith("'''") and line.endswith("'''") and len(line) >3)  \
           or (line.startswith('"""') and line.endswith('"""') and len(line) >3) :
            continue

        # this is either a starting or ending docstring
        elif line.startswith('"""') or line.startswith("'''"):
            docstring = not docstring
            continue

        else:
            nb_lines += 1

    return nb_lines
7

把Python的文档字符串算在“代码行数”里是合理的。通常情况下,注释会被编译器忽略掉,但文档字符串是会被解析的:

可以参考 PEP 257 - 文档字符串规范

文档字符串是一个字符串字面量,它出现在模块、函数、类或方法定义的第一行。这样的文档字符串会成为这个对象的 __doc__ 特殊属性。

...

在Python代码的其他地方出现的字符串字面量也可以作为文档使用。但是它们不会被Python的字节码编译器识别,也无法作为运行时对象的属性访问。

换句话说,文档字符串确实是被编译的,并且在某种程度上,它们构成了程序的代码。此外,它们通常被 doctest模块 用于单元测试,也可以作为命令行工具的使用说明等等。

撰写回答