模块功能
能够同时统计代码量和代码复杂度
支持语言
默认递归分析文件夹
支持下列的一些语言等
C/C++ (works with C++14)
Java
C# (C Sharp)
JavaScript
Objective C
Swift
Python
Ruby
TTCN-3
PHP
Scala
GDScript
安装
Git源码链接 https://github.com/terryyin/lizard
pip: pip install lizard
源码:python setup.py install --install-dir=/path/to/installation/directory/
圈复杂度
圈复杂度是 Thomas J. McCabe 在 1976年开创的软件指标,用来判断程序的复杂度。
这个指标度量源代码中线性独立的路径或分支的数量。
根据 McCabe 所说,一个方法的复杂度最好保持在10 以下。
这是因为对人类记忆力的研究表明,人的短期记忆只能存储 7 件事(偏差为正负 2)。
如果开发人员编写的代码有 50 个线性独立的路径,那么为了在头脑中描绘出方法中发生的情况,需要的记忆力大约超过短期记忆容量的5倍。
简单的方法不会超过人的短期记忆力的极限,因此更容易应付,事实证明它们的错误更少。
Enerjy 在 2008年所做的研究表明,在圈复杂度与错误数量之间有很强的相关性。
复杂度为 11 的类的出错概率为 0.28,而复杂度为 74的类的出错概率会上升到 0.98。
用法案例
usage: lizard [options] [PATH or FILE] [PATH] ...
lizard is an extensible Cyclomatic Complexity Analyzer for many programming
languages including C/C++ (doesn't require all the header files). For more
information visit http://www.lizard.ws
positional arguments:
paths list of the filename/paths.
optional arguments:
-h, --help show this help message and exit
--version show program's version number and exit
-l LANGUAGES, --languages LANGUAGES
List the programming languages you want to analyze. if
left empty, it'll search for all languages it knows.
`lizard -l cpp -l java`searches for C++ and Java code.
The available languages are: cpp, java, csharp,
javascript, python, objectivec, ttcn, ruby, php,
swift, scala, GDScript, go, lua, rust, typescript
列出要分析的编程语言。如果如果留空,它将搜索它知道的所有语言。'Ligal-L CPP-L java '搜索C++和java代码。
cpp, java, csharp,javascript, python, objectivec, ttcn, ruby, php, swift, scala, GDScript, go, lua, rust, typescript
-V, --verbose Output in verbose mode (long function name)
-C CCN, --CCN CCN Threshold for cyclomatic complexity number warning.
The default value is 15. Functions with CCN bigger
than it will generate warning
圈复杂度数警告的阈值,默认值为15,>15会产生警告。
-f INPUT_FILE, --input_file INPUT_FILE
get a list of filenames from the given file
根据给出的文件获取文件名列表
-o OUTPUT_FILE, --output_file OUTPUT_FILE
Output file. The output format is inferred from the
file extension (e.g. .html), unless it is explicitly
specified (e.g. using --xml).
根据格式输出到文件
-L LENGTH, --length LENGTH
Threshold for maximum function length warning. The
default value is 1000. Functions length bigger than it
will generate warning
最大函数长度阈值警告,默认1000,超过报警
-a ARGUMENTS, --arguments ARGUMENTS
Limit for number of parameters
-w, --warnings_only Show warnings only, using clang/gcc's warning format
for printing warnings.
http://clang.llvm.org/docs/UsersManual.html#cmdoption-
fdiagnostics-format
打印警告,只显示warning,clang/gcc's格式
--warning-msvs Show warnings only, using Visual Studio's warning
format for printing warnings.
https://msdn.microsoft.com/en-us/library/yxkt8b26.aspx
打印警告,只显示warning,Visual Studio's格式
-i NUMBER, --ignore_warnings NUMBER
If the number of warnings is equal or less than the
number, the tool will exit normally; otherwise, it
will generate error. If the number is negative, the
tool exits normally regardless of the number of
warnings. Useful in makefile for legacy code.
如果警告数等于或小于number,则工具将正常退出;否则,它将生成错误。
如果数字为负数,则工具正常退出,无论警告的数量。
在遗留代码的makefile中很有用。
-x EXCLUDE, --exclude EXCLUDE
Exclude files that match the pattern. * matches
everything, ? matches any single character,
"./folder/*" exclude everything in the folder
recursively. Multiple patterns can be specified. Don't
forget to add "" around the pattern.
排除与模式匹配的文件。*匹配一切?匹配任何单个字符,“/folder/*”递归地排除文件夹中的所有内容。
可以指定多个模式。不要忘了在模式周围加“”号。
-t WORKING_THREADS, --working_threads WORKING_THREADS
number of working threads. The default value is 1.
Using a bigger number can fully utilize the CPU and
often faster.
默认使用线程数是1,大于这个数会更分的利用cpu或者运行的更快。
-X, --xml Generate XML in cppncss style instead of the tabular
output. Useful to generate report in Jenkins server
生成cppncss样式的XML而不是表格输出。在Jenkins服务器中生成报表很有用
--csv Generate CSV output as a transform of the default
output 生成CSV输出作为默认输出的转换
-H, --html Output HTML report
-m, --modified Calculate modified cyclomatic complexity number ,
which count a switch/case with multiple cases as one
CCN.
计算修正的圈复杂度数,它将一个switch/case视为一个CCN。
-E EXTENSIONS, --extension EXTENSIONS
User the extensions. The available extensions are:
-Ecpre: it will ignore code in the #else branch.
-Ewordcount: count word frequencies and generate tag cloud.
-Eoutside: include the global code as one function.
-EIgnoreAssert: to ignore all code in assert.
-ENS: count nested control structures.
使用扩展。可用的扩展包括:
-Ecpre:它将忽略#else分支中的代码。
-Ewordcount:统计词频并生成标签云。
-Eoutside:将全局代码作为一个函数。
-EIgnoreAssert:忽略assert中的所有代码。
-ENS:计数嵌套控制结构。
-s SORTING, --sort SORTING
Sort the warning with field. The field can be nloc,
cyclomatic_complexity, token_count, p#arameter_count,
etc. Or an customized field.
用字段对警告进行排序。场可以代码行数,圈复杂度,令牌数,参数数或自定义字段。
-T THRESHOLDS, --Threshold THRESHOLDS
Set the limit for a field. The field can be nloc,
cyclomatic_complexity, token_count, parameter_count,
etc. Or an customized file. Lizard will report warning
if a function exceed the limit
设置字段的限制数。可以代码行数,圈复杂度,令牌数,参数数或自定义字段。
如果函数设置超过了限制数会报警。
-W WHITELIST, --whitelist WHITELIST
The path and file name to the whitelist file. It's
'./whitelizard.txt' by default. Find more information
in README.
设置白名单, 默认'./whitelizard.txt'
实际执行常用命令
cd /.../...你的代码目录
cd /.../...你的代码目录
(1)lizard 默认递归检测文件下的所有文件
(2)lizard -o check.txt 将所有文件输出到某个文件
(3)lizard -C 15 检测CCN超过15
(4)lizard -C 15 .\yingjiafupan\run_fupan.py 检测某个文件CCN超过15
结果展示解释
NLOC, the nloc (lines of code without comments), 不包含注释的代码行数
CCN, cyclomatic complexity number, 圈复杂度也就是分支复杂度,最好保持在10 以下
token, token count of functions. token的个数(关键字,标示符,常量,标点符号,操作符)
param, parameter count of functions. 参数统计数就是函数的参数个数
Cnt, Count的缩写
Rt, Rate的缩写
NLOC CCN token PARAM length location
------------------------------------------------
6 1 80 0 11 servers@14-24@.\beixiangzijin\tests\bxzj_test_api.py
2 1 7 1 2 paths@34-35@.\beixiangzijin\tests\bxzj_test_api.py
==========================================================================================
Total nloc Avg.NLOC AvgCCN Avg.token Fun Cnt Warning cnt Fun Rt nloc Rt
------------------------------------------------------------------------------------------
20506 17.1 4.3 140.0 1048 74 0.07 0.38
圈复杂度优化建议
尽量少用 if …else … ,等分支语句
每个函数要有明确的功能实现,不要为了追求行数少而合并功能实现
模型数据的赋值、校验最好放在 model 自己里面
逻辑模块和数据模块要区分开编写
常用降低圈复杂度的方法
1.采用三元表达式替换if else
2.合并条件表达式,比如使用a || b || c
3.拆分成子函数
4.去掉没有必要的else
5.重构函数减少重复代码