Python3 pylint详解 (规范python代码风格)
Pylint简介
Pylint 是一个 Python 代码分析工具,它分析 Python 代码中的错误,查找不符合代码风格标准(Pylint 默认使用的代码风格是 PEP 8,具体信息,请参阅参考资料)和有潜在问题的代码。目前 Pylint 的最新版本是 pylint-0.18.1。
- Pylint 是一个 Python 工具,除了平常代码分析工具的作用之外,它提供了更多的功能:如检查一行代码的长度,变量名是否符合命名标准,一个声明过的接口是否被真正实现等等。
- Pylint 的一个很大的好处是它的高可配置性,高可定制性,并且可以很容易写小插件来添加功能。
- 如果运行两次 Pylint,它会同时显示出当前和上次的运行结果,从而可以看出代码质量是否得到了改进。
- 目前在 eclipse 的 pydev 插件中也集成了 Pylint。
Pylint 具体介绍
Pylint 的安装
Pylint 可以用于所有高于或者等于 2.2 的 Python 版本兼容。需要 logilab-astng(version >= 0.14)和 logilab-common(version >= 0.13)的包(具体信息,请参阅 参考资料),如果是 Python 版本低于 2.3,那么它还需要 optik 包(本文接下来的示例暂不考虑这种情况)。
Pylint 所用到的所有的包的下载地址
logilab-astng 的最新包下载:http://www.logilab.org/856/
logilab-common 的最新包下载:http://www.logilab.org/848/
optik 的包下载:http://optik.sourceforge.net/
Pylint 的最新包下载:http://www.logilab.org/project/pylint
Pylint 在 Linux 上的安装
1. 在 Linux 上,首先安装 Python 的包(高于版本 2.2),并在环境变量 $PATH 中添加 Python 可执行文件的路径。
2. 下载 Pylint、logilab-astng (version >= 0.14) 和 logilab-common (version >= 0.13) 的包 , 使用
tar zxvf *.tar.gz解压缩这些包。
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 的调用命令
1 |
pylint [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 >pylint.conf
,查看 pylint.conf,可以看到 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 的格式如下:
1 |
MESSAGE_TYPE: LINE_NUM:[OBJECT:] MESSAGE |
MESSAGE_TYPE 有如下几种:
(C) 惯例。违反了编码风格标准
(R) 重构。写得非常糟糕的代码。
(W) 警告。某些 Python 特定的问题。
(E) 错误。很可能是代码中的错误。
( 20000 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 13 |
import string #!/usr/bin/env python
import xml.dom.minidom
xmlDom=xml.dom.minidom.parse("identity.xml") organizations = xmlDom.getElementsByTagName('DW') for org in organizations: products = org.getElementsByTagName('linux') for product in products: print 'ID: ' + product.getAttribute('id') print 'Name: ' + product.getAttribute('name') print 'Word Count: ' + product.getAttribute('count') |
清单 4. identity.xml 的内容
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("identity.xml")^ 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("identity.xml")^ 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 4 |
C0111: *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("identity.xml") organizations = xmlDom.getElementsByTagName('DW') for org in organizations: products = org.getElementsByTagName('linux') for product in products: print 'ID: ' + product.getAttribute('id') print 'Name: ' + product.getAttribute('name') print 'Word Count: ' + product.getAttribute('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("identity.xml") ^ 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("identity.xml") organizations = xmldom.getElementsByTagName('DW') for org in organizations: products = org.getElementsByTagName('linux') for product in products: print 'ID: ' + product.getAttribute('id') print 'Name: ' + product.getAttribute('name') print 'Word Count: ' + product.getAttribute('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 >pylint.conf来生成一个示例配置文件,然后编辑其中的
--const-rgx选项。或者也可以直接
pylint --const-rgx='[a-z_][a-z0-9_]{2,30}$' --generate-rcfile >pylint.conf,这样生成的配置文件中
--const-rgx选项直接就是
'[a-z_][a-z0-9_]{2,30}$'了。
以后运行 Pylint 的时候指定配置文件:
pylint --rcfile=pylint.conf dw.py
这样 Pylint 就会按照配置文件
pylint.conf中的选项来指定参数。在一个部门中,大家可以共同使用同一个配置文件,这样就可以保持一致的代码风格。
7. 如果把 report 部分加上,即不使用
--reports=
n,可以看到报告部分的内容。
获取告警帮助信息
如需对某告警类型获取帮助信息,可以使用"pylint --help-msg <msg-id>"命令来获取:
bob@Ubuntu:~$ pylint --help-msg unused-import
:unused-import (W0611): *Unused import %s*
Used when an imported module or variable is not used. This message belongs to
the variables checker.
8. 局部关闭某告警类型
在某些情况,可能需要关闭某文件中的某些告警类型,而非配置文件那种全局配置的情况,可以通过下列的方式来达到目的,通过注释的方式,来禁掉某些检查,如对meth2函数不检查未使用的参数情况。
"""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"""
# pylint: disable=unused-argument
print self\
+ "foo"
---------------------
安装完毕可以在PyCharm中关联pylint
进入PyCharm,从菜单栏,依次进入: File ->Settings ->Tools ->External Tools。
“+”,进行添加。需要填写的部分分别是:“Name”,“Tool Settings ->Programs”、“Tool Settings ->Parameters”、“Tool Settings ->Working directory”。
1、Name:就是你自定义的一个名字,可以是任意的
2、Tool Settings一栏:
Program:填写你pylint执行文件的路径
Arguments: 这里填写的是pylint执行的时候 后面跟的选项列表,每个选项通过空格隔开(例如:$FilePath$ --reports=n其中$FilePath$ 指的是你当前要进行pylint的文件 $FilePath$是必须写的;--rcfile=/usr/lib/python3.6/bin/pylint.conf这个选项是指定了pylint的配置文件
Working directory: 这个是必须写的 可以写:$FileDir$
3、Advanced Options一栏:
Synchronize file after execute: 意思 不是很清楚
Open console for tool output:意思就是执行pylint 会自动打开console 显示所有的输出 下面的两个子选线就是指错误输出和正 常的输出都会显示在console中
配置完毕,选择一个Python程序(此时$FilePath$就是这个选中的文件),右键点击,快捷菜单中会有“Extensions Tools ->Pylint”,点击运行即可。输出结果在执行程序结果的窗口(IDE下半部分)。
通过pylint配置文件 自定义pylint的代码规范
可以通过执行"pylint --generate-rcfile"生成配置文件模板(默认会在pylint可执行文件的所在的目录下),可以在模板文件上定制相关的统一的配置文件。配置文件中包含了master, message control, reports, typecheck, similarities, basic, variables, format, design, classes, imports, exception相关的lint配置信息,用户可以进行私人订制。我的是在:/usr/lib/python3.6/bin/pylint.conf 生成的模板内容如下:
[code][MASTER] # Specify a configuration file. #rcfile= # Python code to execute, usually for sys.path manipulation such as # pygtk.require(). #init-hook= # Profiled execution. profile=no # Add files or directories to the blacklist. They should be base names, not # paths. ignore=CVS # Pickle collected data for later comparisons. persistent=yes # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. load-plugins= [MESSAGES CONTROL] # 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. See also the "--disable" option for examples. #enable= # 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" #disable= disable=logging-not-lazy, line-too-long, trailing-whitespace, bare-except, broad-except [REPORTS] # Set the output format. Available formats are text, parseable, colorized, msvs # (visual studio) and html. You can also give a reporter class, eg # mypackage.mymodule.MyReporterClass. output-format=text # Put messages in a separate file for each module / package specified on the # command line instead of printing them on stdout. Reports (if any) will be # written in a file name "pylint_global.[txt|html]". files-output=no # Tells whether to display a full report or only the messages reports=yes # Python expression which should return a note less than 10 (10 is the highest # note). You have access to the variables errors warning, statement which # respectively contain the number of errors / warnings messages and the total # number of statements analyzed. This is used by the global evaluation report # (RP0004). evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) # Add a comment according to your evaluation note. This is used by the global # evaluation report (RP0004). comment=no # Template used to display messages. This is a python new-style format string # used to format the massage information. See doc for all details #msg-template= [TYPECHECK] # Tells whether missing members accessed in mixin class should be ignored. A # mixin class is detected if its name ends with "mixin" (case insensitive). ignore-mixin-members=yes # List of classes names for which member attributes should not be checked # (useful for classes with attributes dynamically set). ignored-classes=SQLObject # When zope mode is activated, add a predefined set of Zope acquired attributes # to generated-members. zope=no # List of members which are set dynamically and missed by pylint inference # system, and so shouldn't trigger E0201 when accessed. Python regular # expressions are accepted. generated-members=REQUEST,acl_users,aq_parent [SIMILARITIES] # Minimum lines number of a similarity. min-similarity-lines=4 # Ignore comments when computing similarities. ignore-comments=yes # Ignore docstrings when computing similarities. ignore-docstrings=yes # Ignore imports when computing similarities. ignore-imports=no [BASIC] # Required attributes for module, separated by a comma required-attributes= # List of builtins function names that should not be used, separated by a comma bad-functions=map,filter,apply,input # Regular expression which should only match correct module names module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ # Regular expression which should only match correct module level names const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ # Regular expression which should only match correct class names class-rgx=[A-Z_][a-zA-Z0-9]+$ # Regular expression which should only match correct function names function-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct method names method-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct instance attribute names attr-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct argument names argument-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct variable names variable-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct attribute names in class # bodies class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ # Regular expression which should only match correct list comprehension / # generator expression variable names inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ # Good variable names which should always be accepted, separated by a comma good-names=i,j,k,ex,Run,_ # Bad variable names which should always be refused, separated by a comma bad-names=foo,bar,baz,toto,tutu,tata # Regular expression which should only match function or class names that do # not require a docstring. no-docstring-rgx=__.*__ # Minimum line length for functions/classes that require docstrings, shorter # ones are exempt. docstring-min-length=-1 [VARIABLES] # Tells whether we should check for unused import in __init__ files. init-import=no # A regular expression matching the beginning of the name of dummy variables # (i.e. not used). dummy-variables-rgx=_$|dummy # List of additional names supposed to be defined in builtins. Remember that # you should avoid to define new builtins when possible. additional-builtins= [FORMAT] # Maximum number of characters on a single line. max-line-length=120 # Regexp for a line that is allowed to be longer than the limit. ignore-long-lines=^\s*(# )?<?https?://\S+>?$ # Maximum number of lines in a module max-module-lines=1000 # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 # tab). indent-string=' ' [MISCELLANEOUS] # List of note tags to take in consideration, separated by a comma. notes=FIXME,XXX,TODO [DESIGN] # Maximum number of arguments for function / method max-args=5 # Argument names that match this expression will be ignored. Default to name # with leading underscore ignored-argument-names=_.* # Maximum number of locals for function / method body max-locals=15 # Maximum number of return / yield for function / method body max-returns=6 # Maximum number of branch for function / method body max-branches=12 # Maximum number of statements in function / method body max-statements=50 # Maximum number of parents for a class (see R0901). max-parents=7 # Maximum number of attributes for a class (see R0902). max-attributes=7 # Minimum number of public methods for a class (see R0903). min-public-methods=2 # Maximum number of public methods for a class (see R0904). max-public-methods=20 [CLASSES] # List of interface methods to ignore, separated by a comma. This is used for # instance to not check methods defines in Zope's Interface base class. ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by # List of method names used to declare (i.e. assign) instance attributes. defining-attr-methods=__init__,__new__,setUp # List of valid names for the first argument in a class method. valid-classmethod-first-arg=cls # List of valid names for the first argument in a metaclass class method. valid-metaclass-classmethod-first-arg=mcs [IMPORTS] # Deprecated modules which should not be used, separated by a comma deprecated-modules=regsub,TERMIOS,Bastion,rexec # Create a graph of every (i.e. internal and external) dependencies in the # given file (report RP0402 must not be disabled) import-graph= # Create a graph of external dependencies in the given file (report RP0402 must # not be disabled) ext-import-graph= # Create a graph of internal dependencies in the given file (report RP0402 must # not be disabled) int-import-graph= [EXCEPTIONS] # Exceptions that will emit a warning when being caught. Defaults to # "Exception"
检查源码文件
配置好rcfile配置文件后,就可以使用pylint开始对源码文件进行配置检查了,可以通过类似命令"pylint --rcfile=/usr/lib/python3.6/bin/pylint.conf"来完成,命令参数包含配置文件的路径和源码文件路径。我们可以直接在配置文件中按照自己的意愿配置pylint命令怎么执行,以及配置我们自己的代码风格。
pylint官方文档 https://pylint.readthedocs.io/en/latest/
来自:
https://blog.csdn.net/jinguangliu/article/details/43674771
https://www.cnblogs.com/yanzibuaa/p/9145886.html
https://www.cnblogs.com/helloworld7/p/9983462.html
- 如何使用 Pylint 来规范 Python 代码风格
- 如何使用 Pylint 来规范 Python 代码风格
- 如何使用 Pylint 来规范 Python 代码风格
- 如何使用 Pylint 来规范 Python 代码风格
- 如何使用 Pylint 来规范 Python 代码风格(来自IBM)
- 如何使用 Pylint 来规范 Python 代码风格
- 如何使用 Pylint 来规范 Python 代码风格
- 如何使用 Pylint 来规范 Python 代码风格
- 如何使用 Pylint 来规范 Python 代码风格
- python代码检查工具pylint 让你的python更规范
- python代码风格检查工具──pylint
- python代码风格检查工具──pylint
- python代码风格检查工具──pylint
- Python代码规范与pylint
- 在pycharm使用pylint检查python代码规范
- 使用Pylint规范你的Python代码
- [Dynamic Language] Pylint 分析Python代码格式规范
- python代码检查工具pylint 让你的python更规范
- Python代码风格规范
- python代码检查工具pylint 让你的python更规范