Python实现多语言代码行数统计工具:从单文件到多语言支持

叶初
叶初
发布时间:2026-10-14| 6人浏览过
原创

本文详细介绍如何使用Python开发一个灵活的代码行数统计工具。通过逐行解析文件,利用状态标识处理单行与多行注释,并抽象配置常量以支持Python、PHP、Java等多种编程语言。文章涵盖从简化版单文件统计到递归遍历目录、支持命令行参数指定语言类型的完整实现过程,帮助开发者快速掌握项目代码规模分析方法。

问题定义与输出示例

问题定义

我们需要设计一个程序,用于统计项目中的代码行数,包括文件个数、代码行数、注释行数和空行数。设计应具备灵活性,允许通过输入不同参数来统计不同语言的项目,例如:


# type用于指定文件类型
python counter.py --type python

输出示例:

files:10 code_lines:200 comments:100 blanks:20

问题分析与核心思路

问题分析

这看似简单,实则涉及复杂的设计。我们可以将问题分解:若能正确统计单个文件的代码行数,统计整个目录便水到渠成。其中最具挑战性的是多行注释的处理。以Python为例,注释行主要包含以下几种情况:

1、以井号开头的单行注释

# 单行注释

2、多行注释符在同一行的情况

"""这是多行注释""" '''这也是多行注释''' 3、多行注释符

""" 这3行都是注释符 """

我们的思路是采取逐行解析的方式。对于多行注释,需要引入一个额外的标识符 in_multi_comment 来标记当前行是否处于多行注释状态,默认值为 False。当遇到多行注释开始符时,将其置为 True;遇到结束符时,再置为 False。从开始符号到结束符号之间的所有行均视为注释行。

核心知识点与简化版实现

核心知识点

主要涉及如何正确读取文件,以及如何将读取内容作为字符串处理,运用字符串的常用方法进行分析。

简化版实现

我们逐步迭代,先实现一个简化版本,仅统计Python代码的单文件,且不考虑多行注释。这是Python入门级别的功能。关键步骤在于读取每一行后,使用 strip() 方法去除字符串两端的空格和回车符。


# -*- coding: utf-8 -*-
"""
只能统计单行注释的py文件
"""
def parse(path):
 comments = 0
 blanks = 0
 codes = 0
 with open(path, encoding='utf-8') as f:
 for line in f.readlines():
  line = line.strip()
  if line == "":
  blanks += 1
  elif line.startswith("#"):
  comments += 1
  else:
  codes += 1
 return {"comments": comments, "blanks": blanks, "codes": codes}
if __name__ == '__main__':
 print(parse("xxx.py"))

多行注释支持版开发

多行注释支持版

如果只能统计单行注释,该工具的意义有限。只有解决多行注释的统计问题,才能称之为真正的代码统计器。


# -*- coding: utf-8 -*-
"""

该版本可以统计包含多行注释的py文件。


"""
def parse(path):
 in_multi_comment = False # 多行注释符标识符号
 comments = 0
 blanks = 0
 codes = 0
 with open(path, encoding="utf-8") as f:
 for line in f.readlines():
  line = line.strip()
  # 多行注释中的空行当做注释处理
  if line == "" and not in_multi_comment:
  blanks += 1
  # 注释有4种
  # 1. # 井号开头的单行注释
  # 2. 多行注释符在同一行的情况
  # 3. 多行注释符之间的行
  elif line.startswith("#") or \
    (line.startswith('"""') and line.endswith('"""') and len(line)) > 3 or \
   (line.startswith("'''") and line.endswith("'''") and len(line) > 3) or \
   (in_multi_comment and not (line.startswith('"""') or line.startswith("'''"))):
  comments += 1
  # 4. 多行注释符的开始行和结束行
  elif line.startswith('"""') or line.startswith("'''"):
  in_multi_comment = not in_multi_comment
  comments += 1
  else:
  codes += 1
 return {"comments": comments, "blanks": blanks, "codes": codes}
if __name__ == '__main__':
 print(parse("xxx.py"))

针对上述第4种情况,当遇到多行注释符号时,对 in_multi_comment 标识符进行取反操作是关键。这并非简单地置为 False 或 True:第一次遇到 """ 时设为 True,第二次遇到 """ 时视为结束符,取反为 False;以此类推,第三次遇到时再次设为 True。

那么,判断其他语言是否需要重新编写解析函数?仔细观察可知,多行注释的4种情况可以抽象出4个判断条件。因为大部分语言都包含单行注释和多行注释,区别仅在于符号不同。


CONF = {"py": {"start_comment": ['"""', "'''"], "end_comment": ['"""', "'''"], "single": "#"},
 "java": {"start_comment": ["/*"], "end_comment": ["*/"], "single": "//"}}
start_comment = CONF.get(exstansion).get("start_comment")
end_comment = CONF.get(exstansion).get("end_comment")
cond2 = False
cond3 = False
cond4 = False
for index, item in enumerate(start_comment):
 cond2 = line.startswith(item) and line.endswith(end_comment[index]) and len(line) > len(item)
 if cond2:
 break
for item in end_comment:
 if line.startswith(item):
 cond3 = True
 break
for item in start_comment+end_comment:
 if line.startswith(item):
 cond4 = True
 break
if line == "" and not in_multi_comment:
 blanks += 1
# 注释有4种
# 1. # 井号开头的单行注释
# 2. 多行注释符在同一行的情况
# 3. 多行注释符之间的行
elif line.startswith(CONF.get(exstansion).get("single")) or cond2 or \
 (in_multi_comment and not cond3):
 comments += 1
# 4. 多行注释符分布在多行时,开始行和结束行
elif cond4:
 in_multi_comment = not in_multi_comment
 comments += 1
else:
 codes += 1

只需定义一个配置常量,列出所有语言的单行和多行注释符号,对应出 cond1 到 cond4 几种情况即可。剩余任务是通过 os.walk 方法解析多个文件。


def counter(path):
 """
 可以统计目录或者某个文件
 :param path:
 :return:
 """
 if os.path.isdir(path):
 comments, blanks, codes = 0, 0, 0
 list_dirs = os.walk(path)
 for root, dirs, files in list_dirs:
  for f in files:
  file_path = os.path.join(root, f)
  stats = parse(file_path)
  comments += stats.get("comments")
  blanks += stats.get("blanks")
  codes += stats.get("codes")
 return {"comments": comments, "blanks": blanks, "codes": codes}
 else:
 return parse(path)

当然,要使程序更加完善,还需完成多项工作,包括实现命令行解析,允许根据指定参数仅解析特定语言。

补充:Python代码行数统计工具实战

补充说明:

Python实现代码行数统计工具

我们经常需要统计项目的代码行数,但若要实现功能完善的统计,并非易事。今天我们将探讨如何使用Python实现一个代码行统计工具。

基本思路:

首先获取所有文件,然后统计每个文件中代码的行数,最后将各行数相加。

实现的功能:

统计每个文件的行数; 统计总行数; 统计运行时间; 支持指定统计文件类型,排除不想统计的文件类型; 递归统计文件夹下包括子文件件下的文件的行数;

排除空行;


# coding=utf-8
import os
import time
basedir = '/root/script'
filelists = []
# 指定想要统计的文件类型
whitelist = ['php', 'py']
#遍历文件, 递归遍历文件夹中的所有
def getFile(basedir):
 global filelists
 for parent,dirnames,filenames in os.walk(basedir):
  #for dirname in dirnames:
  # getFile(os.path.join(parent,dirname)) #递归
  for filename in filenames:
   ext = filename.split('.')[-1]
   #只统计指定的文件类型,略过一些log和cache文件
   if ext in whitelist:
    filelists.append(os.path.join(parent,filename))
#统计一个文件的行数
def countLine(fname):
 count = 0
 for file_line in open(fname).xreadlines():
  if file_line != '' and file_line != '\n': #过滤掉空行
   count += 1
 print fname + '----' , count
 return count
if __name__ == '__main__' :
 startTime = time.clock()
 getFile(basedir)
 totalline = 0
 for filelist in filelists:
  totalline = totalline + countLine(filelist)
 print 'total lines:',totalline
 print 'Done! Cost Time: %0.2f second' % (time.clock() - startTime) 

运行结果:

[root@pythontab script]# python countCodeLine.py /root/script/test/gametest.php---- 16 /root/script/smtp.php---- 284 /root/script/gametest.php---- 16 /root/script/countCodeLine.py---- 33 /root/script/sendmail.php---- 17 /root/script/test/gametest.php---- 16 total lines: 382 Done! Cost Time: 0.00 second [root@pythontab script]#

该工具只会统计php和python文件,使用非常方便。

总结

以上所述是使用Python设计代码统计工具的详细介绍,希望对大家有所帮助。如果大家有任何疑问,请留言,小编会及时回复。在此非常感谢大家对本站网站的支持!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。