PyCharm 中使用 Pylint 控制 python 代码质量

时间:2021-12-22 08:20:49

Eins

简介

本文主要介绍pylint的配置与使用,如何安装请参考pylint安装,详细信息可参考pylint官方网站的帮助文档Pylint User Manual

获取帮助信息

pylint安装成功后,可以通过运行"pylint --help"来快速查看pylint的帮助信息;相关信息基本能够支撑起快速使用起来pylint的基本功能。

[plain]  view plain  copy
  1. bob@Ubuntu:~$ pylint --help  
  2. No config file found, using default configuration  
  3. Usage:  pylint [options] module_or_package  
  4.   
  5.   Check that a module satisfies a coding standard (and more !).  
  6.   
  7.     pylint --help  
  8.   
  9.   Display this help message and exit.  
  10.   
  11.     pylint --help-msg <msg-id>[,<msg-id>]  
  12.   
  13.   Display help messages about given message identifiers and exit.  
  14.   
  15.   
  16. Options:  
  17.   --version             show program's version number and exit  
  18.   -h, --help            show this help message and exit  
  19.   --long-help           more verbose help.  
  20.   
  21.   Master:  
  22.     --rcfile=<file>     Specify a configuration file.  
  23.     -E, --errors-only   In error mode, checkers without error messages are  
  24.                         disabled and for others, only the ERROR messages are  
  25.                         displayed, and no reports are done by default  
  26.     --ignore=<file>[,<file>...]  
  27.                         Add files or directories to the blacklist. They should  
  28.                         be base names, not paths. [current: CVS]  
  29.   
  30.   Commands:  
  31.     --help-msg=<msg-id>  
  32.                         Display a help message for the given message id and  
  33.                         exit. The value may be a comma separated list of  
  34.                         message ids.  
  35.     --generate-rcfile   Generate a sample configuration file according to the  
  36.                         current configuration. You can put other options  
  37.                         before this one to get them in the generated  
  38.                         configuration.  
  39.   
  40.   Messages control:  
  41.     -e <msg ids>, --enable=<msg ids>  
  42.                         Enable the message, report, category or checker with  
  43.                         the given id(s). You can either give multiple  
  44.                         identifier separated by comma (,) or put this option  
  45.                         multiple time. See also the "--disable" option for  
  46.                         examples.  
  47.     -d <msg ids>, --disable=<msg ids>  
  48.                         Disable the message, report, category or checker with  
  49.                         the given id(s). You can either give multiple  
  50.                         identifiers separated by comma (,) or put this option  
  51.                         multiple times (only on the command line, not in the  
  52.                         configuration file where it should appear only  
  53.                         once).You can also use "--disable=all" to disable  
  54.                         everything first and then reenable specific checks.  
  55.                         For example, if you want to run only the similarities  
  56.                         checker, you can use "--disable=all  
  57.                         --enable=similarities". If you want to run only the  
  58.                         classes checker, but have no Warning level messages  
  59.                         displayed, use"--disable=all --enable=classes  
  60.                         --disable=W"  
  61.   
  62.   Reports:  
  63.     -f <format>, --output-format=<format>  
  64.                         Set the output format. Available formats are text,  
  65.                         parseable, colorized, msvs (visual studio) and html.  
  66.                         You can also give a reporter class, eg  
  67.                         mypackage.mymodule.MyReporterClass. [current: text]  
  68.     -r <y_or_n>, --reports=<y_or_n>  
  69.                         Tells whether to display a full report or only the  
  70.                         messages [current: yes]  
  71.     --msg-template=<template>  
  72.                         Template used to display messages. This is a python  
  73.                         new-style format string used to format the message  
  74.                         information. See doc for all details  

生成配置文件

可以通过"pylint --generate-rcfile"生成配置文件模板,可以在模板文件上定制相关的统一的配置文件。配置文件中包含了master, message control, reports, typecheck, similarities,  basic, variables, format, design, classes, imports, exception相关的lint配置信息,用户可以进行私人订制。

[plain]  view plain  copy
  1. bob@Ubuntu:~$ cat pylint.conf  
  2. [MASTER]  
  3.   
  4. # Specify a configuration file.  
  5. #rcfile=  
  6.   
  7. # Python code to execute, usually for sys.path manipulation such as  
  8. # pygtk.require().  
  9. #init-hook=  
  10.   
  11. # Profiled execution.  
  12. profile=no  
  13.   
  14. # Add files or directories to the blacklist. They should be base names, not  
  15. # paths.  
  16. ignore=CVS  
  17.   
  18. # Pickle collected data for later comparisons.  
  19. persistent=yes  
  20.   
  21. # List of plugins (as comma separated values of python modules names) to load,  
  22. # usually to register additional checkers.  
  23. load-plugins=  
  24.   
  25.   
  26. [MESSAGES CONTROL]  
  27.   
  28. # Enable the message, report, category or checker with the given id(s). You can  
  29. # either give multiple identifier separated by comma (,) or put this option  
  30. # multiple time. See also the "--disable" option for examples.  
  31. #enable=  
  32.   
  33. # Disable the message, report, category or checker with the given id(s). You  
  34. # can either give multiple identifiers separated by comma (,) or put this  
  35. # option multiple times (only on the command line, not in the configuration  
  36. # file where it should appear only once).You can also use "--disable=all" to  
  37. # disable everything first and then reenable specific checks. For example, if  
  38. # you want to run only the similarities checker, you can use "--disable=all  
  39. # --enable=similarities". If you want to run only the classes checker, but have  
  40. # no Warning level messages displayed, use"--disable=all --enable=classes  
  41. # --disable=W"  
  42. #disable=  
  43. disable=logging-not-lazy, line-too-long, trailing-whitespace, bare-except, broad-except  
  44.   
  45.   
  46. [REPORTS]  
  47.   
  48. # Set the output format. Available formats are text, parseable, colorized, msvs  
  49. # (visual studio) and html. You can also give a reporter class, eg  
  50. # mypackage.mymodule.MyReporterClass.  
  51. output-format=text  
  52.   
  53. # Put messages in a separate file for each module / package specified on the  
  54. # command line instead of printing them on stdout. Reports (if any) will be  
  55. # written in a file name "pylint_global.[txt|html]".  
  56. files-output=no  
  57.   
  58. # Tells whether to display a full report or only the messages  
  59. reports=yes  
  60.   
  61. # Python expression which should return a note less than 10 (10 is the highest  
  62. # note). You have access to the variables errors warning, statement which  
  63. # respectively contain the number of errors / warnings messages and the total  
  64. # number of statements analyzed. This is used by the global evaluation report  
  65. # (RP0004).  
  66. evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)  
  67.   
  68. # Add a comment according to your evaluation note. This is used by the global  
  69. # evaluation report (RP0004).  
  70. comment=no  
  71.   
  72. # Template used to display messages. This is a python new-style format string  
  73. # used to format the massage information. See doc for all details  
  74. #msg-template=  
  75.   
  76.   
  77. [TYPECHECK]  
  78.   
  79. # Tells whether missing members accessed in mixin class should be ignored. A  
  80. # mixin class is detected if its name ends with "mixin" (case insensitive).  
  81. ignore-mixin-members=yes  
  82.   
  83. # List of classes names for which member attributes should not be checked  
  84. # (useful for classes with attributes dynamically set).  
  85. ignored-classes=SQLObject  
  86.   
  87. # When zope mode is activated, add a predefined set of Zope acquired attributes  
  88. # to generated-members.  
  89. zope=no  
  90.   
  91. # List of members which are set dynamically and missed by pylint inference  
  92. # system, and so shouldn't trigger E0201 when accessed. Python regular  
  93. # expressions are accepted.  
  94. generated-members=REQUEST,acl_users,aq_parent  
  95.   
  96.   
  97. [SIMILARITIES]  
  98.   
  99. # Minimum lines number of a similarity.  
  100. min-similarity-lines=4  
  101.   
  102. # Ignore comments when computing similarities.  
  103. ignore-comments=yes  
  104.   
  105. # Ignore docstrings when computing similarities.  
  106. ignore-docstrings=yes  
  107.   
  108. # Ignore imports when computing similarities.  
  109. ignore-imports=no  
  110.   
  111.   
  112. [BASIC]  
  113.   
  114. # Required attributes for module, separated by a comma  
  115. required-attributes=  
  116.   
  117. # List of builtins function names that should not be used, separated by a comma  
  118. bad-functions=map,filter,apply,input  
  119.   
  120. # Regular expression which should only match correct module names  
  121. module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$  
  122.   
  123. # Regular expression which should only match correct module level names  
  124. const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$  
  125.   
  126. # Regular expression which should only match correct class names  
  127. class-rgx=[A-Z_][a-zA-Z0-9]+$  
  128.   
  129. # Regular expression which should only match correct function names  
  130. function-rgx=[a-z_][a-z0-9_]{2,30}$  
  131.   
  132. # Regular expression which should only match correct method names  
  133. method-rgx=[a-z_][a-z0-9_]{2,30}$  
  134.   
  135. # Regular expression which should only match correct instance attribute names  
  136. attr-rgx=[a-z_][a-z0-9_]{2,30}$  
  137.   
  138. # Regular expression which should only match correct argument names  
  139. argument-rgx=[a-z_][a-z0-9_]{2,30}$  
  140.   
  141. # Regular expression which should only match correct variable names  
  142. variable-rgx=[a-z_][a-z0-9_]{2,30}$  
  143.   
  144. # Regular expression which should only match correct attribute names in class  
  145. # bodies  
  146. class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$  
  147.   
  148. # Regular expression which should only match correct list comprehension /  
  149. # generator expression variable names  
  150. inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$  
  151.   
  152. # Good variable names which should always be accepted, separated by a comma  
  153. good-names=i,j,k,ex,Run,_  
  154.   
  155. # Bad variable names which should always be refused, separated by a comma  
  156. bad-names=foo,bar,baz,toto,tutu,tata  
  157.   
  158. # Regular expression which should only match function or class names that do  
  159. # not require a docstring.  
  160. no-docstring-rgx=__.*__  
  161.   
  162. # Minimum line length for functions/classes that require docstrings, shorter  
  163. # ones are exempt.  
  164. docstring-min-length=-1  
  165.   
  166.   
  167. [VARIABLES]  
  168.   
  169. # Tells whether we should check for unused import in __init__ files.  
  170. init-import=no  
  171.   
  172. # A regular expression matching the beginning of the name of dummy variables  
  173. # (i.e. not used).  
  174. dummy-variables-rgx=_$|dummy  
  175.   
  176. # List of additional names supposed to be defined in builtins. Remember that  
  177. # you should avoid to define new builtins when possible.  
  178. additional-builtins=  
  179.   
  180.   
  181. [FORMAT]  
  182.   
  183. # Maximum number of characters on a single line.  
  184. max-line-length=120  
  185.   
  186. # Regexp for a line that is allowed to be longer than the limit.  
  187. ignore-long-lines=^\s*(# )?<?https?://\S+>?$  
  188.   
  189. # Maximum number of lines in a module  
  190. max-module-lines=1000  
  191.   
  192. # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1  
  193. # tab).  
  194. indent-string='    '  
  195.   
  196.   
  197. [MISCELLANEOUS]  
  198.   
  199. # List of note tags to take in consideration, separated by a comma.  
  200. notes=FIXME,XXX,TODO  
  201.   
  202.   
  203. [DESIGN]  
  204.   
  205. # Maximum number of arguments for function / method  
  206. max-args=5  
  207.   
  208. # Argument names that match this expression will be ignored. Default to name  
  209. # with leading underscore  
  210. ignored-argument-names=_.*  
  211.   
  212. # Maximum number of locals for function / method body  
  213. max-locals=15  
  214.   
  215. # Maximum number of return / yield for function / method body  
  216. max-returns=6  
  217.   
  218. # Maximum number of branch for function / method body  
  219. max-branches=12  
  220.   
  221. # Maximum number of statements in function / method body  
  222. max-statements=50  
  223.   
  224. # Maximum number of parents for a class (see R0901).  
  225. max-parents=7  
  226.   
  227. # Maximum number of attributes for a class (see R0902).  
  228. max-attributes=7  
  229.   
  230. # Minimum number of public methods for a class (see R0903).  
  231. min-public-methods=2  
  232.   
  233. # Maximum number of public methods for a class (see R0904).  
  234. max-public-methods=20  
  235.   
  236.   
  237. [CLASSES]  
  238.   
  239. # List of interface methods to ignore, separated by a comma. This is used for  
  240. # instance to not check methods defines in Zope's Interface base class.  
  241. ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by  
  242.   
  243. # List of method names used to declare (i.e. assign) instance attributes.  
  244. defining-attr-methods=__init__,__new__,setUp  
  245.   
  246. # List of valid names for the first argument in a class method.  
  247. valid-classmethod-first-arg=cls  
  248.   
  249. # List of valid names for the first argument in a metaclass class method.  
  250. valid-metaclass-classmethod-first-arg=mcs  
  251.   
  252.   
  253. [IMPORTS]  
  254.   
  255. # Deprecated modules which should not be used, separated by a comma  
  256. deprecated-modules=regsub,TERMIOS,Bastion,rexec  
  257.   
  258. # Create a graph of every (i.e. internal and external) dependencies in the  
  259. # given file (report RP0402 must not be disabled)  
  260. import-graph=  
  261.   
  262. # Create a graph of external dependencies in the given file (report RP0402 must  
  263. # not be disabled)  
  264. ext-import-graph=  
  265.   
  266. # Create a graph of internal dependencies in the given file (report RP0402 must  
  267. # not be disabled)  
  268. int-import-graph=  
  269.   
  270.   
  271. [EXCEPTIONS]  
  272.   
  273. # Exceptions that will emit a warning when being caught. Defaults to  
  274. # "Exception"  

检查源码文件

配置好rcfile配置文件后,就可以使用pylint开始对源码文件进行配置检查了,可以通过类似命令"pylint --rcfile=/home/bob/pylint.conf /opt/app/login/login.py"来完成,命令参数包含配置文件的路径和源码文件路径。

pylint会生成检查报告,接下来我们来解析报告的内容:

[plain]  view plain  copy
  1. W: 10, 0: Unused import help (unused-import)  
报告中安装上述的格式生成检查结果,W代表生成的检查级别,级别分为4种:error, warning, refactor, convention;可以根据首字母来对应相应的级别。"10, 0" 代表告警所在源码文件中的行号和列号,可以通过Eclipse中CTRL+L快捷键快速查找所在到问题所在的行。“Unused import help"表述问题的详细信息。”(unused-import)为问题的消息ID信息。

下面的信息是按照消息的类别进行分类,对4种级别的告警信息进行汇总:

[plain]  view plain  copy
  1. Messages by category  
  2. --------------------  
  3.   
  4. +-----------+-------+---------+-----------+  
  5. |type       |number |previous |difference |  
  6. +===========+=======+=========+===========+  
  7. |convention |2      |2        |=          |  
  8. +-----------+-------+---------+-----------+  
  9. |refactor   |0      |0        |=          |  
  10. +-----------+-------+---------+-----------+  
  11. |warning    |11     |11       |=          |  
  12. +-----------+-------+---------+-----------+  
  13. |error      |0      |0        |=          |  
  14. +-----------+-------+---------+-----------+  
下面是按照消息类型进行统计,记录具体告警发生的次数

[plain]  view plain  copy
  1. Messages  
  2. --------  
  3.   
  4. +------------------+------------+  
  5. |message id        |occurrences |  
  6. +==================+============+  
  7. |mixed-indentation |8           |  
  8. +------------------+------------+  
  9. |unused-import     |2           |  
  10. +------------------+------------+  
  11. |invalid-name      |2           |  
  12. +------------------+------------+  
  13. |redefined-builtin |1           |  
  14. +------------------+------------+  

获取告警帮助信息

如需对某告警类型获取帮助信息,可以使用"pylint --help-msg <msg-id>"命令来获取:

[plain]  view plain  copy
  1. bob@Ubuntu:~$ pylint --help-msg unused-import  
  2. :unused-import (W0611): *Unused import %s*  
  3.   Used when an imported module or variable is not used. This message belongs to  
  4.   the variables checker.  

局部关闭某告警类型

在某些情况,可能需要关闭某文件中的某些告警类型,而非配置文件那种全局配置的情况,可以通过下列的方式来达到目的,通过注释的方式,来禁掉某些检查,如对meth2函数不检查未使用的参数情况。

[plain]  view plain  copy
  1. """pylint option block-disable"""  
  2.   
  3. __revision__ = None  
  4.   
  5. class Foo(object):  
  6.     """block-disable test"""  
  7.   
  8.     def __init__(self):  
  9.         pass  
  10.   
  11.     def meth1(self, arg):  
  12.         """this issues a message"""  
  13.         print self  
  14.   
  15.     def meth2(self, arg):  
  16.         """and this one not"""  
  17.         # pylint: disable=unused-argument  
  18.         print self\  
  19.               + "foo"  

小结

通过本文的介绍,基本可以快速使用pylint来对Python代码进行静态代码的检查;如果想获取更多使用或配置信息,可以查看官网的帮助文档:http://docs.pylint.org/

参考资料

1. pylint安装

2. http://docs.pylint.org/



Zwei

pylint在项目中的使用


需求背景:

Pylint 是一个 Python 代码分析工具,它分析 Python 代码中的错误,查找不符合代码风格标准和有潜在问题的代码。

Pylint 是一个 Python 工具,除了平常代码分析工具的作用之外,它提供了更多的功能:如检查一行代码的长度,变量名是否符合命名标准,一个声明过的接口是否被真正实现等等。

Pylint 的一个很大的好处是它的高可配置性,高可定制性,并且可以很容易写小插件来添加功能。

项目中需要做代码规范检查,所以研究一下pylint的使用。

pylint使用:

  • 安装pylint:

>pip install pylint

确认pylint安装成功:

>pylint --version
No config file found, using default configuration
pylint 1.6.5,
astroid 1.4.9
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v.1500 64 bit (AMD64)]
  • 生成默认配置文件:

>pylint --persistent=n --generate-rcfile > pylint.conf
No config file found, using default configuration

查看当前目录下,已经生成了名为pylint.conf的文件,该文件中的配置项都是pylint的默认配置,比较大400多行。

  • check单个文件:

>pylint --rcfile=pylint.conf manage.py
  • check结果总览:
************* Module manage
C:  1, 0: Missing module docstring (missing-docstring) W: 14,12: Unused import django (unused-import) 

报告中上述格式为检查结果总览:C表示convention,规范;W表示warning,告警;pylint结果总共有四个级别:error,warning,refactor,convention,可以根据首字母确定相应的级别。1, 0表示告警所在文件中的行号和列号。

  • 4种级别告警汇总:
Messages by category
+-----------+-------+---------+-----------+
|type |number |previous |difference | +===========+=======+=========+===========+ |convention |1 |NC       |NC |
+-----------+-------+---------+-----------+
|refactor |0      |NC |NC         | +-----------+-------+---------+-----------+ |warning    |1 |NC       |NC |
+-----------+-------+---------+-----------+
|error |0      |NC |NC         | +-----------+-------+---------+-----------+ 
  • 消息类型统计:
Messages
+------------------+------------+
|message id |occurrences | +==================+============+ |mixed-indentation |8 |
+------------------+------------+
|unused-import |2           | +------------------+------------+ |invalid-name      |2 |
+------------------+------------+
|redefined-builtin |1           | +------------------+------------+ 
  • check整个工程:

    目前看只能一个module一个module的pylint,但是如果在工程根目录下添加init.py文件,即把工程当做一个python包的话,可以对整个工程进行pylint。
pylint api(api为包名称)

重命名pylint.conf为.pylintrc,即不需要每次执行都带上--rcfile参数了:

pylintrc in the current working directory
.pylintrc in the current working directory
If the current working directory is in a Python module, Pylint searches up the hierarchy of Python modules until it finds a pylintrc file. This allows you to specify coding standards on a module-by-module basis. Of course, a directory is judged to be a Python module if it contains an __init__.py file.
The file named by environment variable PYLINTRC
if you have a home directory which isn’t /root:
.pylintrc in your home directory
.config/pylintrc in your home directory
/etc/pylintrc

pylint集成到PyCharm:

打开File->设置对话框:

PyCharm 中使用 Pylint 控制 python 代码质量
settings.png

单击 ToolsExternal Tools,添加External Tool:
PyCharm 中使用 Pylint 控制 python 代码质量
Create Tool.png

这样修改完代码后,Tools菜单下就会多出pylint工具了:

PyCharm 中使用 Pylint 控制 python 代码质量
pylint.png

如果想要pylint当前文件,只要运行上图的pylint工具即可。


参考资料:




Drei

PyCharm 中使用 Pylint 控制代码质量

1) Pylint安装

- Windows下:

直接在 cmd 下使用 pip install pylint 即可(如果 pip 不可用,首先安装最新版 Python,会默认安装 pip,或者找到 pip 的安装脚本先装 pip)。装好后,pylint.exe 的大体位置在 C:/Python27/Scripts/ 底下,将此路径添加到环境变量 PATH。

- Linux 下:

直接在 Terminal 中使用 $ sudo pip install pylint 安装即可。装好后,pylint 会在 /usr/bin/pylint

 

2) 配置 PyCharm

File > Settings... > Tools > External Tools,点击 + 号添加,如下图配置,

其中,

Program设置为: 指向 pylint 的实际目录,此处以 Linux 目录为例。

Parameters 设置为 (用户可根据自己的情况,选择 pylint 输出信息显示格式和要 disable 的项目):--output-format=parseable --disable=R --disable=C0102,C0103,C0111,C0301,C0302,C0303,C0304,C0305,W0120,W0123,W0401,W0603,W0612,W0614,W0621,W0622,W0703,E1003,E1101 $FilePath$

注:为了防止 Pylint 打印找不到 配置文件的 warning,可以在当前工程目录下新建一个空的文件,取名为 .pylintrc,再在上述参数中加入选项 --rcfile=path/to/.pylintrc 即可。

Working Direcroty 设置为:$FileDir$

 

PyCharm 中使用 Pylint 控制 python 代码质量

 

3) 使用 Pylint 评估代码质量

当写完一个脚本后,直接右键单击,选择 External Tools > pylint,运行后可得到当前代码质量,和改进建议。