问题
设计一个程序,用于统计一个项目中的代码行数,包括文件个数,代码行数,注释行数,空行行数。尽量设计灵活一点可以通过输入不同参数来统计不同语言的项目,例如:
# 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"))
新闻热点
疑难解答