Python 代码检查之Pylint

本文介绍了Pylint,一款用于Python代码审查的工具,它能检查PEP8规范、发现错误并提供建议。讲解了安装、使用方法,并展示了如何定制输出格式、生成报表和配置Jenkins集成。

Pylint是什么

pylint是一个python代码检查工具

Pylint能干什么

这里列出了很多,单是我想前三种应该是最有用的

  • 检查python代码符不符合PEP8规范
  • 检查代码中的错误
  • 提供重构建议

下面就用一个例子来展开说明

如何安装

pip install pylint

如何使用

pylint python file

# or

pylint python package

例子:

import logging

logging.basicConfig(level=logging.INFO)


def print_info(msg: str, other: str):
    logging.info(msg)


def print_warn(msg: str):
    logging.warning(msg)


def print_error(msg: str):
    logging.error(msg)


def print_error(msg: str, number: int):
    logging.error(msg)


class Test(object):

    def xx(self, msg):
        logging.info(msg)

 

在控制台执行

(python_learn) 07L0219050006DD:python_learn darren.zhang$ pwd
/Users/darren.zhang/project/workspace/python_learn
(python_learn) 07L0219050006DD:python_learn darren.zhang$ pylint pylint_example/
************* Module pylint_example.pylint_example
pylint_example/pylint_example.py:26:0: C0305: Trailing newlines (trailing-newlines)
pylint_example/pylint_example.py:1:0: C0114: Missing module docstring (missing-module-docstring)
pylint_example/pylint_example.py:6:0: C0116: Missing function or method docstring (missing-function-docstring)
pylint_example/pylint_example.py:6:25: W0613: Unused argument 'other' (unused-argument)
pylint_example/pylint_example.py:10:0: C0116: Missing function or method docstring (missing-function-docstring)
pylint_example/pylint_example.py:14:0: C0116: Missing function or method docstring (missing-function-docstring)
pylint_example/pylint_example.py:18:0: E0102: function already defined line 14 (function-redefined)
pylint_example/pylint_example.py:18:0: C0116: Missing function or method docstring (missing-function-docstring)
pylint_example/pylint_example.py:18:26: W0613: Unused argument 'number' (unused-argument)
pylint_example/pylint_example.py:22:0: C0115: Missing class docstring (missing-class-docstring)
pylint_example/pylint_example.py:22:0: R0205: Class 'Test' inherits from object, can be safely removed from bases in python3 (useless-object-inheritance)
pylint_example/pylint_example.py:24:4: C0103: Method name "xx" doesn't conform to snake_case naming style (invalid-name)
pylint_example/pylint_example.py:24:4: C0116: Missing function or method docstring (missing-function-docstring)
pylint_example/pylint_example.py:24:4: R0201: Method could be a function (no-self-use)
pylint_example/pylint_example.py:22:0: R0903: Too few public methods (1/2) (too-few-public-methods)

--------------------------------------------------------------------
Your code has been rated at -4.62/10 (previous run: -3.85/10, -0.77)

(python_learn) 07L0219050006DD:python_learn darren.zhang$ 

Pylint总共有五种检查级别

  • – C convention related checks for coding standard violation
  • – R refactoring related checks
  • – W various warnings
  • – E errors, for probable bugs in the code
  • – F fatal, if an error occurred which prevented pylint from doing further processing.

我在这里模拟了前四种

第一个问题,我想修改格式怎么办,默认的格式为:

{path}:{line}:{column}: {msg_id}: {msg} ({symbol})

可参考:http://pylint.pycqa.org/en/latest/user_guide/output.html

简单修改一个格式如下:

'{msg_id}: {path}: [{line:3d},{column:2d}]: {msg}'

执行如下命令:

(python_learn) 07L0219050006DD:python_learn darren.zhang$ pylint pylint_example/ --msg-template='{msg_id}: {path}: [{line:3d},{column:2d}]: {msg}'
************* Module pylint_example.pylint_example
C0305: pylint_example/pylint_example.py: [ 26, 0]: Trailing newlines
C0114: pylint_example/pylint_example.py: [  1, 0]: Missing module docstring
C0116: pylint_example/pylint_example.py: [  6, 0]: Missing function or method docstring
W0613: pylint_example/pylint_example.py: [  6,25]: Unused argument 'other'
C0116: pylint_example/pylint_example.py: [ 10, 0]: Missing function or method docstring
C0116: pylint_example/pylint_example.py: [ 14, 0]: Missing function or method docstring
E0102: pylint_example/pylint_example.py: [ 18, 0]: function already defined line 14
C0116: pylint_example/pylint_example.py: [ 18, 0]: Missing function or method docstring
W0613: pylint_example/pylint_example.py: [ 18,26]: Unused argument 'number'
C0115: pylint_example/pylint_example.py: [ 22, 0]: Missing class docstring
R0205: pylint_example/pylint_example.py: [ 22, 0]: Class 'Test' inherits from object, can be safely removed from bases in python3
C0103: pylint_example/pylint_example.py: [ 24, 4]: Method name "xx" doesn't conform to snake_case naming style
C0116: pylint_example/pylint_example.py: [ 24, 4]: Missing function or method docstring
R0201: pylint_example/pylint_example.py: [ 24, 4]: Method could be a function
R0903: pylint_example/pylint_example.py: [ 22, 0]: Too few public methods (1/2)

--------------------------------------------------------------------
Your code has been rated at -4.62/10 (previous run: -4.62/10, +0.00)

可以根据自己需求修改输出格式。

第二个问题,我要修改输出格式,比如说json格式,怎么做

查看帮助文档:

pylint --help
...

  Reports:
    -f <format>, --output-format=<format>
                        Set the output format. Available formats are text,
                        parseable, colorized, json and msvs (visual studio).
                        You can also give a reporter class, e.g.
                        mypackage.mymodule.MyReporterClass. [current: text]

指定-f 支持json格式

(python_learn) 07L0219050006DD:python_learn darren.zhang$ pylint pylint_example/  -f json
[
    {
        "type": "convention",
        "module": "pylint_example.pylint_example",
        "obj": "",
        "line": 26,
        "column": 0,
        "path": "pylint_example/pylint_example.py",
        "symbol": "trailing-newlines",
        "message": "Trailing newlines",
        "message-id": "C0305"
    },
...
]

第三个问题,如何生成报表

pylint --help
...

  Reports:
    -r <y_or_n>, --reports=<y_or_n>
                        Tells whether to display a full report or only the
                        messages. [current: no]
(python_learn) 07L0219050006DD:python_learn darren.zhang$ pylint pylint_example/  -r y
************* Module pylint_example.pylint_example
pylint_example/pylint_example.py:26:0: C0305: Trailing newlines (trailing-newlines)
pylint_example/pylint_example.py:1:0: C0114: Missing module docstring (missing-module-docstring)
pylint_example/pylint_example.py:6:0: C0116: Missing function or method docstring (missing-function-docstring)
pylint_example/pylint_example.py:6:25: W0613: Unused argument 'other' (unused-argument)
pylint_example/pylint_example.py:10:0: C0116: Missing function or method docstring (missing-function-docstring)
pylint_example/pylint_example.py:14:0: C0116: Missing function or method docstring (missing-function-docstring)
pylint_example/pylint_example.py:18:0: E0102: function already defined line 14 (function-redefined)
pylint_example/pylint_example.py:18:0: C0116: Missing function or method docstring (missing-function-docstring)
pylint_example/pylint_example.py:18:26: W0613: Unused argument 'number' (unused-argument)
pylint_example/pylint_example.py:22:0: C0115: Missing class docstring (missing-class-docstring)
pylint_example/pylint_example.py:22:0: R0205: Class 'Test' inherits from object, can be safely removed from bases in python3 (useless-object-inheritance)
pylint_example/pylint_example.py:24:4: C0103: Method name "xx" doesn't conform to snake_case naming style (invalid-name)
pylint_example/pylint_example.py:24:4: C0116: Missing function or method docstring (missing-function-docstring)
pylint_example/pylint_example.py:24:4: R0201: Method could be a function (no-self-use)
pylint_example/pylint_example.py:22:0: R0903: Too few public methods (1/2) (too-few-public-methods)


Report
======
13 statements analysed.

Statistics by type
------------------

+---------+-------+-----------+-----------+------------+---------+
|type     |number |old number |difference |%documented |%badname |
+=========+=======+===========+===========+============+=========+
|module   |2      |NC         |NC         |50.00       |0.00     |
+---------+-------+-----------+-----------+------------+---------+
|class    |1      |NC         |NC         |0.00        |0.00     |
+---------+-------+-----------+-----------+------------+---------+
|method   |1      |NC         |NC         |0.00        |100.00   |
+---------+-------+-----------+-----------+------------+---------+
|function |4      |NC         |NC         |0.00        |0.00     |
+---------+-------+-----------+-----------+------------+---------+



Raw metrics
-----------

+----------+-------+------+---------+-----------+
|type      |number |%     |previous |difference |
+==========+=======+======+=========+===========+
|code      |16     |53.33 |NC       |NC         |
+----------+-------+------+---------+-----------+
|docstring |0      |0.00  |NC       |NC         |
+----------+-------+------+---------+-----------+
|comment   |0      |0.00  |NC       |NC         |
+----------+-------+------+---------+-----------+
|empty     |14     |46.67 |NC       |NC         |
+----------+-------+------+---------+-----------+



Duplication
-----------

+-------------------------+------+---------+-----------+
|                         |now   |previous |difference |
+=========================+======+=========+===========+
|nb duplicated lines      |0     |NC       |NC         |
+-------------------------+------+---------+-----------+
|percent duplicated lines |0.000 |NC       |NC         |
+-------------------------+------+---------+-----------+



Messages by category
--------------------

+-----------+-------+---------+-----------+
|type       |number |previous |difference |
+===========+=======+=========+===========+
|convention |9      |NC       |NC         |
+-----------+-------+---------+-----------+
|refactor   |3      |NC       |NC         |
+-----------+-------+---------+-----------+
|warning    |2      |NC       |NC         |
+-----------+-------+---------+-----------+
|error      |1      |NC       |NC         |
+-----------+-------+---------+-----------+



% errors / warnings by module
-----------------------------

+------------------------------+-------+--------+---------+-----------+
|module                        |error  |warning |refactor |convention |
+==============================+=======+========+=========+===========+
|pylint_example.pylint_example |100.00 |100.00  |100.00   |100.00     |
+------------------------------+-------+--------+---------+-----------+



Messages
--------

+---------------------------+------------+
|message id                 |occurrences |
+===========================+============+
|missing-function-docstring |5           |
+---------------------------+------------+
|unused-argument            |2           |
+---------------------------+------------+
|useless-object-inheritance |1           |
+---------------------------+------------+
|trailing-newlines          |1           |
+---------------------------+------------+
|too-few-public-methods     |1           |
+---------------------------+------------+
|no-self-use                |1           |
+---------------------------+------------+
|missing-module-docstring   |1           |
+---------------------------+------------+
|missing-class-docstring    |1           |
+---------------------------+------------+
|invalid-name               |1           |
+---------------------------+------------+
|function-redefined         |1           |
+---------------------------+------------+




--------------------------------------------------------------------
Your code has been rated at -4.62/10 (previous run: -4.62/10, +0.00)

第四个问题,报表不是应该是html吗,支持吗?

答案不支持

要想支持,需要再安装一个工具把json格式的输出转化成html报告,当然也可以自己根据json格式的输出,自己写代码生成一个报告,这个应该不难,使用jinja2可以搞定,下边介绍的工具也是用的jinja2模版。

pip install -q pylint-json2html

pylint pylint_example/  -f json |  pylint-json2html -o pylint.html

当然这个html报告也很简单,如若您不满意,那就只好自己搞了。

第五个问题,返回值是什么?

exit codemeaningstderr stream message
0no error 
1fatal message issued 
2error message issued 
4warning message issued 
8refactor message issued 
16convention message issued 
32usage error
  • "internal error while receiving resultsfrom child linter" "Error occurred, stopping the linter."
  • "<return of linter.help()>"
  • "Jobs number <#> should be greater than 0"

以上表格是各种类型对应的返回值,如果出现多个则累加。举个例子,上边的例子中分别出现了convention,refactor,warning和error四种,那么对应的返回值就是16 + 8 + 4 + 2 = 30,那么我们来验证一下:

(python_learn) 07L0219050006DD:python_learn darren.zhang$ pylint pylint_example/
************* Module pylint_example.pylint_example
pylint_example/pylint_example.py:26:0: C0305: Trailing newlines (trailing-newlines)
pylint_example/pylint_example.py:1:0: C0114: Missing module docstring (missing-module-docstring)
pylint_example/pylint_example.py:6:0: C0116: Missing function or method docstring (missing-function-docstring)
pylint_example/pylint_example.py:6:25: W0613: Unused argument 'other' (unused-argument)
pylint_example/pylint_example.py:10:0: C0116: Missing function or method docstring (missing-function-docstring)
pylint_example/pylint_example.py:14:0: C0116: Missing function or method docstring (missing-function-docstring)
pylint_example/pylint_example.py:18:0: E0102: function already defined line 14 (function-redefined)
pylint_example/pylint_example.py:18:0: C0116: Missing function or method docstring (missing-function-docstring)
pylint_example/pylint_example.py:18:26: W0613: Unused argument 'number' (unused-argument)
pylint_example/pylint_example.py:22:0: C0115: Missing class docstring (missing-class-docstring)
pylint_example/pylint_example.py:22:0: R0205: Class 'Test' inherits from object, can be safely removed from bases in python3 (useless-object-inheritance)
pylint_example/pylint_example.py:24:4: C0103: Method name "xx" doesn't conform to snake_case naming style (invalid-name)
pylint_example/pylint_example.py:24:4: C0116: Missing function or method docstring (missing-function-docstring)
pylint_example/pylint_example.py:24:4: R0201: Method could be a function (no-self-use)
pylint_example/pylint_example.py:22:0: R0903: Too few public methods (1/2) (too-few-public-methods)

--------------------------------------------------------------------
Your code has been rated at -4.62/10 (previous run: -4.62/10, +0.00)

(python_learn) 07L0219050006DD:python_learn darren.zhang$ echo $?
30

第六个问题,我要集成在Jenkins做一系列构建,不希望中途停止。能不能做?

答案能,为什么会有这个问题,因为上例返回值是30,是非0值,那么就会导致Jenkins直接失败,不会再执行后续的构建,那么就需要让他返回0,从而不影响后续构建。

pylint --help
...

    --exit-zero         Always return a 0 (non-error) status code, even if
                        lint errors are found. This is primarily useful in
                        continuous integration scripts.
(python_learn) 07L0219050006DD:python_learn darren.zhang$ pylint pylint_example/ --exit-zero
************* Module pylint_example.pylint_example
pylint_example/pylint_example.py:26:0: C0305: Trailing newlines (trailing-newlines)
pylint_example/pylint_example.py:1:0: C0114: Missing module docstring (missing-module-docstring)
...

--------------------------------------------------------------------
Your code has been rated at -4.62/10 (previous run: -4.62/10, +0.00)

(python_learn) 07L0219050006DD:python_learn darren.zhang$ echo $?
0

这样就可以了。

第七个问题,我用pylint作为验证工具,如果不符合代码规范或有警告甚至错误,我想让Jenkins停止,不要exit 0,但是由于我是一个老的项目,可能之前的代码不符合规范,短时间又没有精力去改老的代码,但是都不能有Error类型,应该怎么办?

这个问题听起来就是一个需求--过滤指定的类型,针对这个需求是只要 没有Error类型,通过就可以了,也就是说,只检查Error,有则失败,无则通过,这个是可以实现的

pylint --help
...

    -E, --errors-only   In error mode, checkers without error messages are
                        disabled and for others, only the ERROR messages are
                        displayed, and no reports are done by default.
(python_learn) 07L0219050006DD:python_learn darren.zhang$ pylint pylint_example/ -E
************* Module pylint_example.pylint_example
pylint_example/pylint_example.py:18:0: E0102: function already defined line 14 (function-redefined)

第八个问题,针对一个全新的项目,要求很高,不能有Refactor以上的错误,或者要能灵活指定级别的检查方式,有没有?

答案是有的。

pylint --help
...

    -e <msg ids>, --enable=<msg ids>
                        Enable the message, report, category or checker with
                        the given id(s). You can either give multiple
                        identifier separated by comma (,) or put this option
                        multiple time (only on the command line, not in the
                        configuration file where it should appear only once).
                        See also the "--disable" option for examples.
    -d <msg ids>, --disable=<msg ids>
                        Disable the message, report, category or checker with
                        the given id(s). You can either give multiple
                        identifiers separated by comma (,) or put this option
                        multiple times (only on the command line, not in the
                        configuration file where it should appear only once).
                        You can also use "--disable=all" to disable everything
                        first and then reenable specific checks. For example,
                        if you want to run only the similarities checker, you
                        can use "--disable=all --enable=similarities". If you
                        want to run only the classes checker, but have no
                        Warning level messages displayed, use "--disable=all
                        --enable=classes --disable=W".
(python_learn) 07L0219050006DD:python_learn darren.zhang$ pylint pylint_example/ -d C,R,W
************* Module pylint_example.pylint_example
pylint_example/pylint_example.py:18:0: E0102: function already defined line 14 (function-redefined)

--------------------------------------------------------------------
Your code has been rated at 6.15/10 (previous run: -4.62/10, +10.77)

(python_learn) 07L0219050006DD:python_learn darren.zhang$ pylint pylint_example/ -d C,R
************* Module pylint_example.pylint_example
pylint_example/pylint_example.py:6:25: W0613: Unused argument 'other' (unused-argument)
pylint_example/pylint_example.py:18:0: E0102: function already defined line 14 (function-redefined)
pylint_example/pylint_example.py:18:26: W0613: Unused argument 'number' (unused-argument)

------------------------------------------------------------------
Your code has been rated at 4.62/10 (previous run: 6.15/10, -1.54)

很容易就过滤出来了。

第九个问题,我有很多个package,或者有很多个文件需要校验,能不能多线程同时执行?

答案是可以的

pylint --help
...

    -j <n-processes>, --jobs=<n-processes>
                        Use multiple processes to speed up Pylint. Specifying
                        0 will auto-detect the number of processors available
                        to use. [current: 1]
pylint pylint_example/ -j 4

以上是我这两台使用pylint的经验整理,希望有帮助

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值