强制执行 Python 代码风格/标准的工具
我正在寻找一个工具来检查Python代码的编码风格。
对于PHP,我看到有一个叫做Code Sniffer的工具,还有一个小的perl脚本被Drupal使用。那Python有没有类似的工具呢?
4 个回答
在接手一个已有的(老旧的)项目时,我在寻找一个能强制执行pep8风格的工具时,发现了这个StackOverflow的问题。
https://github.com/hhatto/autopep8
autopep8 -i yourpythonsourcefile.py
这个工具会自动把所有源代码转换成符合pep8规范的格式。我在我的老旧项目上试过,效果非常好。所以我想在这里更新一下我的回答。
过去我主要使用 PyLint,它可以帮你找出一些问题,比如你用了未定义的变量,或者导入了一些没用到的东西等等。
不过它有时候会啰嗦,抱怨一些像是行数超过80个字符、变量不符合特定格式、类的公共方法太少、方法缺少文档字符串等问题。
比如,对于下面的脚本..
import os
import somefakelib
def myfunc(x):
blah = "Something"
print os.listdir( x+blh )
PyLint 会生成以下信息:
C: 1: Missing docstring
F: 2: Unable to import 'somefakelib' (No module named somefakelib)
C: 4:myfunc: Missing docstring
C: 4:myfunc: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)
C: 4:myfunc: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)
E: 6:myfunc: Undefined variable 'blh'
W: 5:myfunc: Unused variable 'blah'
W: 2: Unused import somefakelib
这些都是合理的抱怨,但我通常会关闭很多关于规范和重构的提示。你可以通过在代码中添加注释来关闭特定的提示:
#pylint:disable-msg=R0903,C0103,R0903,F0401,C0301
..或者在运行 PyLint 命令时通过命令行参数来关闭:
pylint --disable-msg=R0903,C0103,R0903,F0401,C0301 myfile.py
在关闭了上述提示后,它会为上面的代码生成以下信息:
C: 1: Missing docstring
C: 4:myfunc: Missing docstring
E: 6:myfunc: Undefined variable 'blh'
W: 5:myfunc: Unused variable 'blah'
W: 2: Unused import somefakelib
PyLint 还会生成一个“代码报告”,包括文件的代码行数、注释行数、文档字符串行数、空白行数等,按类别统计消息数量,并给你的代码打个“分数”——10分表示没有消息,0分一般表示有语法错误。
另一个选择是 PyFlakes,我觉得它的啰嗦程度稍微少一点(我最近开始用它替代 PyLint)。同样使用上面的脚本,PyFlakes 给出的信息是:
example.py:2: 'somefakelib' imported but unused
example.py:6: undefined name 'blh'
我使用的最后一个选项是 pep8.py
,顾名思义,它是用来检查 PEP8 规范的。它是最严格的脚本,强制执行一些像是函数/类前后要有正确的空行、代码周围的空格、正确的4个空格缩进等等。
在上面的代码上运行时,它会产生以下结果:
example.py:4:1: E302 expected 2 blank lines, found 1
example.py:6:23: E201 whitespace after '('
example.py:6:32: W292 no newline at end of file
它主要是检查代码风格,比如空格是否正确,而不像 PyLint 或 PyFlakes 那样进行深入的静态分析,所以我通常会把 pep8.py 和 PyLint 或 PyFlakes 一起使用。
pep8.py
最初是在 python 邮件列表上发布的,但里面的下载链接现在已经失效了。你可以在 cburroughs 的 GitHub 镜像上找到一些小修复,地址是 github.com/cburroughs/pep8.py,或者你也可以从 一个旧版本 下载未修改的版本。
PyChecker 也是一个选择,虽然我没有使用过它。