统计代码行(重新优化了一下)

  写了一个统计项目代码有效(无效)行数的脚本,作为一个基础脚本的实练,主要实现步骤:

1、使用os.walk()遍历多层级项目的所有文件及文件夹
2、os.path.join()拼接完整的文件路径

3、with open() as 方法打开文件,可以免关闭文件操作
4、使用开关方法来识别区分是否为文档注释或着多行注释的内容
5、无效行定义:
① 空白行(包含只有空格、回车、空白等)
② 所有文档注释
③ 单行注释
④ 多行注
(目前实现java、python,其他可以添加)代码如下:

#encoding=utf-8
import os
class CountLinesOfValuableCode(object):
def __init__(self,dirsPath,choice,*suffix):
'''
:param dirs_list type: list 统计有效代码行的文件路径
:param files_list type:list 所有需要被统计的文件路径
:param choice type:number 统计或者不统计的后面的后缀名元组,输入0为排除统计,输入其他为统计
:param suffix type:tuple 不执行的文件后缀名
:param valuable_lines_number type:number 有效代码行数
:param unvaluable_lines_number type:number 无效代码行数
'''
self.dirsPath=dirsPath
self.choice = choice
self.suffix=suffix
self.files_list=[]
self.valuable_lines_number=0
self.unvaluable_lines_number=0

def LookForFile(self):
try:
if os.path.exists(self.dirsPath) and os.path.isdir(self.dirsPath):
for rootpath,dirs,files in os.walk(self.dirsPath): #递归遍历所有文件及文件夹
for file in files:
file_name_path = os.path.join(rootpath, file) #拼接完整的文件路径
if self.choice==0:
if os.path.isfile(file_name_path) and os.path.splitext(file_name_path)[1] not in self.suffix: #排除日志文件等
self.files_list.append(file_name_path)
else:
if os.path.isfile(file_name_path) and os.path.splitext(file_name_path)[1] in self.suffix: #排除日志文件等
self.files_list.append(file_name_path)
print("需要统计行数的文件路径是:%s"%self.files_list)
print("需要统计行数的文件数量是:%s"%len(self.files_list))
return (self.files_list,len(self.files_list))
elif os.path.exists(self.dirsPath) and os.path.isfile(self.dirsPath):
self.files_list.append(self.dirsPath)
return (self.files_list,len(self.files_list))
else:
print("输入的路径'%s'不存在!!!"%self.dirsPath)
return (self.files_list,len(self.files_list))
except Exception as e:
print(e)

def CountCodeLines(self):
for file_path in self.files_list:
swicth=0 #0表示非文档说明,1表示开始文档说明
if os.path.splitext(file_path)[1]==".py": #判断是python文件
with open(file_path,"r",encoding="utf-8") as fq:
lines_list=fq.readlines() #读取文件所有内容,并生成list
for line in lines_list:
if swicth==0 and line.strip()=="": #非文档说明的空行
self.unvaluable_lines_number+=1
elif swicth==0 and line.lstrip().startswith("#"): #非文档说明的注释
self.unvaluable_lines_number += 1
elif swicth==0 and (line.lstrip().startswith('"""') or line.lstrip().startswith("'''")): #文档注释开始
self.unvaluable_lines_number += 1
swicth=1
elif swicth==1 and (line.rstrip().endswith('"""') or line.rstrip().endswith("'''")): #文档注释结束
swicth = 0
self.unvaluable_lines_number += 1
elif swicth==1 and not (line.lstrip().startswith('"""') or line.lstrip().startswith("'''"))
and not (line.rstrip().endswith('"""') or line.rstrip().endswith("'''")): #文档注释内容
self.unvaluable_lines_number += 1
else: #有效代码行
self.valuable_lines_number+=1
elif os.path.splitext(file_path)[1]==".java": #判断是java文件
with open(file_path,"r",encoding="utf-8") as fq:
lines_list=fq.readlines() #读取文件所有内容,并生成list
for line in lines_list:
if swicth==0 and line.strip()=="": #非文档说明的空行
self.unvaluable_lines_number+=1
elif swicth==0 and line.lstrip().startswith("//"): #非文档说明的注释
self.unvaluable_lines_number += 1
elif swicth==0 and (line.lstrip().startswith('/**') or line.lstrip().startswith("/*")): #文档注释或者多行注释开始
self.unvaluable_lines_number += 1
swicth=1
elif swicth==1 and line.rstrip().endswith('*/'): #文档注释或者多行注释结束
swicth = 0
self.unvaluable_lines_number += 1
elif swicth==1 and not (line.lstrip().startswith('/**') or line.lstrip().startswith("/*"))
and not (line.rstrip().endswith('*/') or line.rstrip().endswith("*/")): #文档注释内容
self.unvaluable_lines_number += 1
else: #有效代码行
self.valuable_lines_number+=1
else:
with open(file_path,"r",encoding="utf-8") as fq:
lines_list=fq.readlines() #读取文件所有内容,并生成list
for line in lines_list:
if line.strip()=="": #空行
self.unvaluable_lines_number+=1
else: #有效代码行
self.valuable_lines_number+=1

print("有效行数是%s"%self.valuable_lines_number)
print("无效行数是%s"%self.unvaluable_lines_number)
return (self.valuable_lines_number,1,self.unvaluable_lines_number)







if __name__ =="__main__":
counter=CountLinesOfValuableCode(r"E:whiteMouseProductCountFilesLine2020.log",1,".log",".py",".java")
counter.LookForFile()
counter.CountCodeLines()