前言
本篇文章讨论怎么用python程序统计一个项目的代码行数,以java项目为例
一、读取所有的程序文件
首先要做的是,提供一个项目目录,根据目录的路径来找出所有的源代码文件,这里参考这篇文章(blog.csdn.net/m0_59081230…
该方法的三个参数分别为:项目的路径、文件列表、目录列表,其中文件列表、目录列表可以设置为list = [],方法会返回该项目中的所有目录和文件的绝对路径,以便后面使用。
def get_file_path(root_path, file_list, dir_list):
# 获取该目录下所有的文件名称和目录名称
dir_or_files = os.listdir(root_path)
for dir_file in dir_or_files:
# 获取目录或者文件的路径
dir_file_path = os.path.join(root_path, dir_file)
# 判断该路径为文件还是路径
if os.path.isdir(dir_file_path):
dir_list.append(dir_file_path)
# 递归获取所有文件和目录的路径
get_file_path(dir_file_path, file_list, dir_list)
else:
file_list.append(dir_file_path)
二、读取代码文件,进行统计
主方法
if __name__ == "__main__":
# 根目录路径
root_path = r"C:\Users\10765\Desktop\java"
# 用来存放所有的文件路径
file_list = []
# 用来存放所有的目录路径
dir_list = []
# 获取目录下的所有目录和文件
get_file_path(root_path, file_list, dir_list)
# 未过滤的代码总数
code_sum = 0
# 代码行统计
code_count = 0
# 遍历所有的文件
for i in file_list:
# 获取所有的java文件
if str(i).endswith('.java'):
# 打开
f = open(str(i), encoding='GB2312', errors='ignore')
# 获取文件的行
lines = f.readlines()
# 讲文件的行数赋值给code_sum
code_sum += lines.__len__()
# 过滤掉空行、注释、导包行
code_count += filtrate_code(lines)
print("总代码行数:" + str(code_sum) + "行")
print("去掉空行、注释、导包行后的代码行数:" + str(code_count) + "行")
过滤方法:去掉了代码中的空行、注释和代码最上面的导包行
def filtrate_code(lines):
# 该文件的代码行数
sum = lines.__len__()
# 空行统计
blank_count = 0
# 单行注释统计
line_count = 0
# 多行注释统计的临时存储变量
lines_temp_count = 0
# 多行注释统计
lines_count = 0
# 多行注释的范围
flag = False
# 导包行
package_count = 0
# 遍历每一行
for line in lines:
# 空行判读
if line in ['\n', '\r\n']:
blank_count += 1
# 单行注释判断
if line.strip().startswith("//"):
line_count += 1
# 多行注释判断
if flag:
lines_temp_count += 1
# 多行注释起始判断
if line.strip().startswith("/**"):
# 统计赋值为1
lines_temp_count = 1
# 多行注释开启
flag = True
# 多行注释结尾判断
if line.strip().startswith("*/"):
# 将临时统计赋值给lines_count
lines_count += lines_temp_count
# 关闭多行注释开关
flag = False
# 重新赋值临时统计
lines_temp_count = 0
# 导包行统计
if line.strip().startswith("package"):
package_count += 1
# 返回过滤后的代码行数
return sum - blank_count - line_count - package_count - lines_count
三、执行结果
我这里以我桌面的文件夹为例,大家可以把路径换成需要统计的项目路径,运行结果如下
总结
程序首先遍历项目内的所有文件,再根据源代码文件的特点(.java)来读取代码文件,最后根据代码内的文本特点去掉空行、注释等一些内容。
其中较为复杂的是多行注释的统计,我这里设置了一个flag和一个临时存储多行注释的变量lines_temp_count:如果为多行注释,flag = True,lines_temp_count++;判断多行注释结束,flag = False,将lines_temp_count赋值给一个新变量,并将lines_temp_count赋值为初始值0。
# 多行注释判断
if flag:
lines_temp_count += 1
# 多行注释起始判断
if line.strip().startswith("/**"):
# 统计赋值为1
lines_temp_count = 1
# 多行注释开启
flag = True
# 多行注释结尾判断
if line.strip().startswith("*/"):
# 将临时统计赋值给lines_count
lines_count += lines_temp_count
# 关闭多行注释开关
flag = False
# 重新赋值临时统计
lines_temp_count = 0
完整代码如下
import os
def get_file_path(root_path, file_list, dir_list):
# 获取该目录下所有的文件名称和目录名称
dir_or_files = os.listdir(root_path)
for dir_file in dir_or_files:
# 获取目录或者文件的路径
dir_file_path = os.path.join(root_path, dir_file)
# 判断该路径为文件还是路径
if os.path.isdir(dir_file_path):
dir_list.append(dir_file_path)
# 递归获取所有文件和目录的路径
get_file_path(dir_file_path, file_list, dir_list)
else:
file_list.append(dir_file_path)
def filtrate_code(lines):
# 该文件的代码行数
sum = lines.__len__()
# 空行统计
blank_count = 0
# 单行注释统计
line_count = 0
# 多行注释统计的临时存储变量
lines_temp_count = 0
# 多行注释统计
lines_count = 0
# 多行注释的范围
flag = False
# 导包行
package_count = 0
# 遍历每一行
for line in lines:
# 空行判读
if line in ['\n', '\r\n']:
blank_count += 1
# 单行注释判断
if line.strip().startswith("//"):
line_count += 1
# 多行注释判断
if flag:
lines_temp_count += 1
# 多行注释起始判断
if line.strip().startswith("/**"):
# 统计赋值为1
lines_temp_count = 1
# 多行注释开启
flag = True
# 多行注释结尾判断
if line.strip().startswith("*/"):
# 将临时统计赋值给lines_count
lines_count += lines_temp_count
# 关闭多行注释开关
flag = False
# 重新赋值临时统计
lines_temp_count = 0
# 导包行统计
if line.strip().startswith("package"):
package_count += 1
# 返回过滤后的代码行数
return sum - blank_count - line_count - package_count - lines_count
if __name__ == "__main__":
# 根目录路径
root_path = r"C:\Users\10765\Desktop\java"
# 用来存放所有的文件路径
file_list = []
# 用来存放所有的目录路径
dir_list = []
# 获取目录下的所有目录和文件
get_file_path(root_path, file_list, dir_list)
# 未过滤的代码总数
code_sum = 0
# 代码行统计
code_count = 0
# 遍历所有的文件
for i in file_list:
# 获取所有的java文件
if str(i).endswith('.java'):
# 打开
f = open(str(i), encoding='GB2312', errors='ignore')
# 获取文件的行
lines = f.readlines()
# 讲文件的行数赋值给code_sum
code_sum += lines.__len__()
# 过滤掉空行、注释、导包行
code_count += filtrate_code(lines)
print("总代码行数:" + str(code_sum) + "行")
print("去掉空行、注释、导包行后的代码行数:" + str(code_count) + "行")