写一个Python程序来统计项目的代码行数

0 阅读5分钟

前言

本篇文章讨论怎么用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) + "行")

首次发布

hezhongying.blog.csdn.net/article/det…