> pip install pylint
若下载遇到问题,可以参考此篇文章,更改软件源。
> pylint --version
pylint 2.8.3
astroid 2.5.6
Python 3.7.9
>pylint --persistent=n --generate-rcfile > pylint.conf
No config file found, using default configuration
会在当前目录下,生成 pylint.conf 文件,该文件中的配置项都是 pylint 的默认配置。
> pylint --help
> pylint --long-help (查看更多帮助)
使用 simplecaesar.py python 脚本作为测试文件
1 #!/usr/bin/env python3
2
3 import string;
4
5 shift = 3
6 choice = input("would you like to encode or decode?")
7 word = input("Please enter text")
8 letters = string.ascii_letters + string.punctuation + string.digits
9 encoded = ''
10 if choice == "encode":
11 for letter in word:
12 if letter == ' ':
13 encoded = encoded + ' '
14 else:
15 x = letters.index(letter) + shift
16 encoded = encoded + letters[x]
17 if choice == "decode":
18 for letter in word:
19 if letter == ' ':
20 encoded = encoded + ' '
21 else:
22 x = letters.index(letter) - shift
23 encoded = encoded + letters[x]
24
25 print(encoded)
>pylint --rcfile=pylint.conf simplecaesar.py
************* Module simplecaesar
C: 1, 0: Missing module docstring (missing-docstring)
W: 14,12: Unused import django (unused-import)
每次命令添加 --rcfile
选项会比较繁琐,重命名pylint.conf
为.pylintrc
,即不需要每次执行都带上--rcfile
参数了。
> pylint package_name(package_name为包名称,根目录下需添加init.py)
> pylint simplecaesar.py
************* Module simplecaesar
simplecaesar.py【模块名称】:3:0:【行号:列号】 W0301【W 代表检查级别, 303 为编号】: Unnecessary semicolon【详细消息】 (unnecessary-semicolon)【问题消息ID号, <msg-id>】
simplecaesar.py:1:0: C0114: Missing module docstring (missing-module-docstring)
simplecaesar.py:5:0: C0103: Constant name "shift" doesn't conform to UPPER_CASE naming style (invalid-name)
simplecaesar.py:9:0: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
simplecaesar.py:13:12: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
-----------------------------------
Your code has been rated at 7.37/10
所有告警类别
Output:
Using the default text output, the message format is :
MESSAGE_TYPE: LINE_NUM:[OBJECT:] MESSAGE
There are 5 kind of message types :
* (C) convention, for programming standard violation [不符合编程规范]
* (R) refactor, for bad code smell [需重构]
* (W) warning, for python specific problems [警告]
* (E) error, for probable bugs in the code [错误]
* (F) fatal, if an error occurred which prevented pylint from doing
further processing.[致命错误]
可以通过 pylint --help-msg <msg-id>
获取更多告警帮助信息
>pylint --help-msg trailing-whitespace
:trailing-whitespace (C0303): *Trailing whitespace*
Used when there is whitespace between the end of a line and the newline. This
message belongs to the format checker.
根据意见,在第二行增加文档字符串,去除第三行;
1 #!/usr/bin/env python3
2 """This script prompts a user to enter a message to encode or decode
3 using a classic Caesar shift substitution (3 letter shift)"""
4
5 import string
6
7 shift = 3
8 choice = input("would you like to encode or decode?")
9 word = input("Please enter text")
10 letters = string.ascii_letters + string.punctuation + string.digits
11 encoded = ''
12 if choice == "encode":
13 for letter in word:
14 if letter == ' ':
15 encoded = encoded + ' '
16 else:
17 x = letters.index(letter) + shift
18 encoded = encoded + letters[x]
19 if choice == "decode":
20 for letter in word:
21 if letter == ' ':
22 encoded = encoded + ' '
23 else:
24 x = letters.index(letter) - shift
25 encoded = encoded + letters[x]
26
27 print(encoded)
robertk01 Desktop$ pylint simplecaesar.py
************* Module simplecaesar
simplecaesar.py:7:0: C0103: Constant name "shift" doesn't conform to UPPER_CASE naming style (invalid-name)
simplecaesar.py:11:0: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
simplecaesar.py:15:12: C0103: Constant name "encoded" doesn't conform to UPPER_CASE naming style (invalid-name)
------------------------------------------------------------------
Your code has been rated at 8.42/10 (previous run: 7.37/10, +1.05)
比起上一版程序,评分提高 1.05,只剩下 invalid-name
信息。
这是因为 Pylint 中遵从 PEP 8 对象命名规范,使用大写,小写以及分隔符来定义变量、函数和类名,Pylint 通过正则表达式验证, (([A-Z_][A-Z1-9_]*)|(__.*__))$
。例子中,常数变量应该采用全大写,这和 Pylint 缺省的规范不一致。当然也可以通过自定义是常数为全小数 [a-z_][a-z0-9_]{2,30}$
。
> pylint --const-rgx='[a-z_][a-z0-9_]{2,30}$' simplecaesar.py
-------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 8.42/10, +1.58)
**方法1:**输出terminal
import pylint.lint
pylint_opts = ['--version']
pylint.lint.Run(pylint_opts)
方法2: 静默运行
from pylint import epylint as lint
(pylint_stdout, pylint_stderr) = lint.py_run('module_name.py', return_std=True)
# 可在py_run() 第一个参数位置添加 pylint option
from pylint import epylint as lint
(pylint_stdout, pylint_stderr) = lint.py_run('module_name.py --disable C0114', return_std=True)
消息模板选项 --msg-template="{path}:{line}: {category} ({msg_id}, {symbol}, {obj}) {msg}"
以及--reports=n
是epylint
模块隐式定义.
使用[生成默认配置文件](#3. 生成默认配置文件)操作可以简化繁琐的配置过程,快速定义默认的全面的配置选项。你有两种方式使用配置文件,第一种使用--rcfile
参数,第二种 pylint 按如下顺序搜索配置文件,选择第一个出现的。
pylintrc
in the current working directory.pylintrc
in the current working directorypyproject.toml
in the current working directory, providing it has at least one tool.pylint.
section.setup.cfg
in the current working directory, providing it has at least one pylint.
sectionpylintrc
file. This allows you to specify coding standards on a module-by-module basis. Of course, a directory is judged to be a Python package if it contains an __init__.py
file.PYLINTRC
当然你可以在基础的配置上,手动调整一些配置,如下为常见的配置:
--ignore=<file[,file...]>
Files or directories to be skipped. They should be base names, not paths.
--output=<file>
Specify an output file, 输出到本地文件
--output-format=<format>
Select output format (text, json, custom). a comma-separated list of formats(多个格式,好像不能输出). Possible values are: json, parseable, colorized and msvs (visual studio)
--msg-template=<template>
Modify text output message template. the default format:{path}:{line}:{column}: {msg_id}: {msg} ({symbol}) The format string uses the Python new format syntax and the following fields are available :
--list-msgs
Generate pylint’s messages.
--list-msgs-enabled
Display a list of what messages are enabled and disabled with the given configuration.
--full-documentation
Generate pylint’s full documentation, in reST format.
常用例子
pylint --output=pylint_test.json --output-format=json test.py
pylint --msg-template='{msg_id}:{line:3d},{column}: {obj}: {msg}'
Visual Studio compatible format (former 'msvs' output format):{path}({line}): [{msg_id}{obj}] {msg}
Parseable (Emacs and all, former 'parseable' output format) format: {path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
"""pylint option block-disable"""
__revision__ = None
class Foo(object):
"""block-disable test"""
def __init__(self):
pass
def meth1(self, arg):
"""this issues a message"""
print(self)
def meth2(self, arg):
"""and this one not 关闭一个block的unused-argument错误"""
# pylint: disable=unused-argument
print(self\
+ "foo")
def meth3(self):
"""test one line disabling 关闭一行"""
# no error
print(self.bla) # pylint: disable=no-member
# error
print(self.blop)
def meth4(self):
"""test re-enabling 重使能"""
# pylint: disable=no-member
# no error
print(self.bla)
print(self.blop)
# pylint: enable=no-member
# error
print(self.blip)
def meth5(self):
"""test IF sub-block re-enabling"""
# pylint: disable=no-member
# no error
print(self.bla)
if self.blop:
# pylint: enable=no-member
# error
print(self.blip)
else:
# no error
print(self.blip)
# no error
print(self.blip)
def meth6(self):
"""test TRY/EXCEPT sub-block re-enabling"""
# pylint: disable=no-member
# no error
print(self.bla)
try:
# pylint: enable=no-member
# error
print(self.blip)
except UndefinedName: # pylint: disable=undefined-variable
# no error
print(self.blip)
# no error
print(self.blip)
def meth7(self):
"""test one line block opening disabling"""
if self.blop: # pylint: disable=no-member
# error
print(self.blip)
else:
# error
print(self.blip)
# error
print(self.blip)
def meth8(self):
"""test late disabling"""
# error
print(self.blip)
# pylint: disable=no-member
# no error
print(self.bla)
print(self.blop)