Python3pylint详解(规范python代码风格)
Pylint简介
Pylint 是⼀个 Python 代码分析⼯具,它分析 Python 代码中的错误,查不符合代码风格标准(Pylint 默认使⽤的代码风格是 PEP 8,具体信息,请参阅参考资料)和有潜在问题的代码。⽬前 Pylint 的最新版本是 pylint-0.18.1。
Pylint 是⼀个 Python ⼯具,除了平常代码分析⼯具的作⽤之外,它提供了更多的功能:如检查⼀⾏代码的长度,变量名是否符合命名标准,⼀个声明过的接⼝是否被真正实现等等。
Pylint 的⼀个很⼤的好处是它的⾼可配置性,⾼可定制性,并且可以很容易写⼩插件来添加功能。
如果运⾏两次 Pylint,它会同时显⽰出当前和上次的运⾏结果,从⽽可以看出代码质量是否得到了改进。
⽬前在 eclipse 的 插件中也集成了 Pylint。
Pylint 具体介绍
Pylint 的安装
Pylint 可以⽤于所有⾼于或者等于 2.2 的 Python 版本兼容。需要 (version >= 0.14)和 (version >= 0.13)的包(具体信息,请参阅 参考资料),如果是 Python 版本低于 2.3,那么它还需要 optik 包(本⽂接下来的⽰例暂不考虑这种情况)。
Pylint 所⽤到的所有的包的下载地址
Pylint 在 Linux 上的安装
1. 在 Linux 上,⾸先安装 Python 的包(⾼于版本
2.2),并在环境变量 $PATH 中添加 Python 可执⾏⽂件的路径。
2. 下载 Pylint、logilab-astng (version >= 0.14) 和 logilab-common (version >= 0.13) 的包 , 使⽤ tar zxvf *.解压缩这些包。
3. 依次进⼊ logilab-astng、logilab-common 和 Pylint 解开的⽂件夹中,运⾏命令 Python setup.py install来安装。
4. 安装完成后,就可以通过 pylint [options] module_or_package来调⽤ Pylint 了。
Pylint 在 Windows 上的安装
1. 安装 Python 的包(⾼于版本
2.2),右键单击桌⾯上的我的电脑图标,选择属性,⾼级,环境变量,在 $PATH 中添加 Python 的安装路径,如 C:\Python26\。
2. 使⽤解压缩⼯具解压缩所有的包。
3. 打开命令⾏窗⼝,使⽤ cd依次进⼊ logilab-astng、logilab-common 和 Pylint 解开的⽂件夹中,运⾏命令 python setup.py install来安装。
4. 安装完成后,在 Python 的安装路径下出现⼀个 Scripts ⽂件夹,⾥⾯包含⼀些 bat 脚本,如 pylint.bat 等。
5. 为了使调⽤ pylint.bat 的时候不需要输⼊完整路径,在 Python 的安装⽬录下创建 pylint.bat 的重定向⽂件,这是⼀个纯⽂本⽂件pylint.bat,⾥⾯包含 pylint.bat 的实际路径,如:C:\Python26\Scripts\pylint.bat。
6. 安装完成后,可以通过 pylint [options] module_or_package来调⽤ Pylint 了。
Pylint 的调⽤
清单 1. Pylint 的调⽤命令
1pylint [options] module_or_package
使⽤ Pylint 对⼀个模块 module.py 进⾏代码检查:
1. 进⼊这个模块所在的⽂件夹,运⾏ pylint [options] module.py
这种调⽤⽅式是⼀直可以⼯作的,因为当前的⼯作⽬录会被⾃动加⼊ Python 的路径中。
2. 不进⼊模块所在的⽂件夹,运⾏ pylint [options] directory/module.py
这种调⽤⽅式当如下条件满⾜的时候是可以⼯作的:directory 是个 Python 包 ( ⽐如包含⼀个 __init__.py ⽂件 ),或者 directory 被加⼊了 Python 的路径中。
使⽤ Pylint 对⼀个包 pakage 进⾏代码检查:
1. 进⼊这个包所在⽂件夹,运⾏ pylint [options] pakage。
这种调⽤⽅式是⼀直可以⼯作的,因为当前的⼯作⽬录会被⾃动加⼊ Python 的路径中。
2. 不进⼊包所在的⽂件夹,运⾏ pylint [options] directory/ pakage。
这种情况下当如下条件满⾜的时候是可以⼯作的:directory 被加⼊了 Python 的路径中。⽐如在 Linux 上,export
PYTHONPATH=$PYTHONPATH: directory。
此外,对于安装了 tkinter 包的机器,可以使⽤命令 pylint-gui打开⼀个简单的 GUI 界⾯,在这⾥输⼊模块或者包的名字 ( 规则同命令⾏ ),点击 Run,Pylint 的输出会在 GUI 中显⽰。
Pylint 的常⽤命令⾏参数
-h,--help
显⽰所有帮助信息。
--generate-rcfile
可以使⽤ pylint --generate-rcfile 来⽣成⼀个配置⽂件⽰例。可以使⽤重定向把这个配置⽂件保存下来⽤做以后使⽤。也可以在前⾯加上其它选项,使这些选项的值被包含在这个产⽣的配置⽂件⾥。如:pylint --persistent=n --generate-rcfile > f,查看f,可以看到 persistent=no,⽽不再是其默认值 yes。
--rcfile=<file>
指定⼀个配置⽂件。把使⽤的配置放在配置⽂件中,这样不仅规范了⾃⼰代码,也可以⽅便地和别⼈共享这些规范。
-i <y_or_n>, --include-ids=<y_or_n>
在输出中包含 message 的 id, 然后通过 pylint --help-msg=<msg-id>来查看这个错误的详细信息,这样可以具体地定位错误。
-r <y_or_n>, --reports=<y_or_n>
默认是 y, 表⽰ Pylint 的输出中除了包含源代码分析部分,也包含报告部分。
--files-output=<y_or_n>
将每个 module /package 的 message 输出到⼀个以 pylint_module/package. [txt|html] 命名的⽂件中,如果有 report 的话,输出到名为 pylint_global.[txt|html] 的⽂件中。默认是输出到屏幕上不输出到⽂件⾥。
-f <format>, --output-format=<format>
设置输出格式。可以选择的格式有 text, parseable, colorized, msvs (visual studio) 和 html, 默认的输出格式是 text。
--disable-msg=<msg ids>
禁⽌指定 id 的 message. ⽐如说输出中包含了 W0402 这个 warning 的 message, 如果不希望它在输出中出现,可以使⽤ --disable-msg= W0402
Pylint 的输出
Pylint的默认输出格式是原始⽂本(raw text)格式 ,可以通过 -f <format>,--output-format=<format> 来指定别的输出格式如html等等。在Pylint的输出中有如下两个部分:源代码分析部分和报告部分。
源代码分析部分:
对于每⼀个 Python 模块,Pylint 的结果中⾸先显⽰⼀些"*"字符 , 后⾯紧跟模块的名字,然后是⼀系列的 message, message 的格式如下:
1MESSAGE_TYPE: LINE_NUM:[OBJECT:] MESSAGE
MESSAGE_TYPE 有如下⼏种:
(C) 惯例。违反了编码风格标准
(R) 重构。写得⾮常糟糕的代码。
(W) 警告。某些 Python 特定的问题。
python格式化输出format(E) 错误。很可能是代码中的错误。
(F) 致命错误。阻⽌ Pylint 进⼀步运⾏的错误。清单 2. Pylint 中的 utils 模块的输出结果
1 2 3 4 5 6************* Module utils
C: 88:Message: Missing docstring
R: 88:Message: Too few public methods (0/2)
C:183:MessagesHandlerMixIn._cat_ids: Missing docstring
R:183:MessagesHandlerMixIn._cat_ids: Method could be a function
R:282:MessagesHandlerMixIn.list_messages: Too many branches (14/12)
报告部分:
在源代码分析结束后⾯,会有⼀系列的报告,每个报告关注于项⽬的某些⽅⾯,如每种类别的 message 的数⽬,模块的依赖关系等等。具体来说,报告中会包含如下的⽅⾯:
检查的 module 的个数。
对于每个 module, 错误和警告在其中所占的百分⽐。⽐如有两个 module A 和 B, 如果⼀共检查出来 4 个错误,1 个错误是在 A 中,3 个错误是在 B 中,那么 A 的错误的百分⽐是 25%, B 的错误的百分⽐是 75%。
错误,警告的总数量。
使⽤ Pylint 分析 Python 代码的具体⽰例
下⾯是⼀个从 xml ⽂件中读取⼀些值并显⽰出来的⼀段 Python 代码 dw.py,代码如下:
清单 3. 源码
1 2 3 4 5 6 7 8 9 10 11 12 13import string
#!/usr/bin/env python
import xml.dom.minidom
xmlDom=xml.dom.minidom.parse("l")
organizations = ElementsByTagName('DW') for org in organizations:
products = ElementsByTagName('linux')
for product in products:
print 'ID: ' + Attribute('id')
print 'Name: ' + Attribute('name')
print 'Word Count: ' + Attribute('count')
清单 4. l 的内容
1 2 3 4 5<IBM>
<DW>
<linux id="100"name="python"count="3000"/> </DW>
</IBM>
这时候使⽤ Pylint 的结果(这是从 html 格式的输出中拷贝的)为:
清单 5. Pylint 的分析结果
1 2 3 4 5 6 7************* Module dw
C:1:Missing docstring
C:5:Operator not preceded by a space xmlDom=xml.dom.minidom.parse("l") ^ C:5:Invalid name "xmlDom" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
C:6:Invalid name "organizations" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
Report 部分省略
输出中第⼀部分是源代码分析,第⼆部分是报告。输出结果中有这么多信息,从哪⾥开始分析呢?⾸先使⽤如下的步骤来分析代码:
1. 因为输出结果太长,所以可以先不让它输出报告部分,先根据源代码分析部分来出代码中的问题。使⽤选项 "--reports=n"。
2. 使⽤选项 "--include-ids=y"。可以获取到源代码分析部分每条信息的 ID。
清单 6. 使⽤ pylint --reports=n --include-ids=y dw.py 的结果
1 2 3 4 5************* Module dw
C0111: 1: Missing docstring
C0322: 5: Operator not preceded by a space xmlDom=xml.dom.minidom.parse("l") ^ C0103: 5: Invalid name "xmlDom" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
C0103: 6: Invalid name "organizations" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
每个信息前⾯都会加上⼀个 id, 如果不理解这个信息的意思,可以通过 pylint --help-msg=id来查看。清单 7. 使⽤ pylint --help-msg= C0111 的结果
1 2 3 4C0111: *Missing docstring*
Used when a module, function, class or method has no docstring. Some special methods like __init__ doesn't necessary require a docstring.
This message belongs to the basic checker.
3. 开始分析每个源代码中的问题。从上⾯知道,第⼀个问题的原因是缺少 docstring,在代码中增加 docstring, 修改后的代码如下:清单 8. 增加 docstring 修改后的源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14#!/usr/bin/env python
"""This script parse the content of a xml file"""
import xml.dom.minidom
xmlDom=xml.dom.minidom.parse("l")
organizations = ElementsByTagName('DW') for org in organizations:
products = ElementsByTagName('linux')
for product in products:
print 'ID: ' + Attribute('id')
print 'Name: ' + Attribute('name')
print 'Word Count: ' + Attribute('count')
重新运⾏ pylint --reports=n --include-ids=y dw.py,结果为:清单 9. 运⾏结果
1 2 3 4 5 6************* Module dw
C0322: 7: Operator not preceded by a space
xmlDom=xml.dom.minidom.parse("l")
^
C0103: 7: Invalid name "xmlDom" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
C0103: 8: Invalid name "organizations" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
可以看到源代码中的第⼀个问题已被解决。
4. 关于第⼆个 C0322 的问题,这⾥的分析结果说明得⽐较清楚,是代码第七⾏中的等号运算符两边没有空格。我们在这⾥加上空格,重新运⾏ pylint --reports=n --include-ids=y dw.py,结果为:
清单 10. 运⾏结果
1 2 3************* Module dw
C0103: 7: Invalid name "xmlDom" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
C0103: 8: Invalid name "organizations" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
5. 可以看到现在问题只剩下 C0103 了。这⾥的意思是变量命名规则应该符合后⾯正则表达式的规定。Pylint 定义了⼀系列针对变量,函数,类等的名字的命名规则。实际中我们不⼀定要使⽤这样的命名规则,我们可以定义使⽤正则表达式定义⾃⼰的命名规则,⽐如使⽤选项--const-rgx='[a-z_][a-z0-9_]{2,30}$',我们将变量 xmlDom改为 xmldom, 代码如下:
清单 11. 将变量 xmlDom 改为 xmldom 后的源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14#!/usr/bin/env python
"""This script parse the content of a xml file"""
import xml.dom.minidom
xmldom = xml.dom.minidom.parse("l")
organizations = ElementsByTagName('DW') for org in organizations:
products = ElementsByTagName('linux')
for product in products:
print 'ID: ' + Attribute('id')
print 'Name: ' + Attribute('name')
print 'Word Count: ' + Attribute('count')
运⾏ pylint --reports=n --include-ids=y --const-rgx='[a-z_][a-z0-9_]{2,30}$' dw.py,结果中就没有任何问题了。
6. 如果希望⼀个组⾥的⼈都使⽤这些统⼀的规则,来规范⼀个部门的代码风格。⽐如说⼤家都使⽤ --const-rgx='[a-z_][a-z0-9_]{2,30}$'作为命名规则,那么⼀个⽐较便捷的⽅法是使⽤配置⽂件。
使⽤ pylint --generate-rcfile > f来⽣成⼀个⽰例配置⽂件,然后编辑其中的 --const-rgx选项。或者也可以直接 pylint --const-rgx='[a-z_][a-z0-9_]{2,30}$' --generate-rcfile > f,这样⽣成的配置⽂件中 --const-rgx选项直接就是 '[a-z_][a-z0-9_]{2,30}$'了。
以后运⾏ Pylint 的时候指定配置⽂件:pylint --f dw.py
这样 Pylint 就会按照配置⽂件 f中的选项来指定参数。在⼀个部门中,⼤家可以共同使⽤同⼀个配置⽂件,这样就可以保持⼀致的代码风格。
7. 如果把 report 部分加上,即不使⽤ --reports=n,可以看到报告部分的内容。
获取告警帮助信息
如需对某告警类型获取帮助信息,可以使⽤"pylint --help-msg <msg-id>"命令来获取:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论