如何配置pylint以获得更高的精度

2024-04-25 19:31:08 发布

您现在位置:Python中文网/ 问答频道 /正文

从pylint获得假阳性

考虑此代码:

previous = None
for word in ['you', 'cannot', 'be', 'serious']:
    if previous is not None:
        print(previous[0], word)
    previous = word

以下是输出(这里没有意外):

$ python3 test.py
y cannot
c be
b serious

使用pylint检查它会得到以下结果:

$ pylint3 test.py
No config file found, using default configuration
************* Module test
C:  1, 0: Missing module docstring (missing-docstring)
C:  1, 0: Constant name "previous" doesn't conform to UPPER_CASE naming style (invalid-name)
E:  4,14: Value 'previous' is unsubscriptable (unsubscriptable-object)

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

如您所见,pylint抱怨表达式previous[0],因为previous被初始化为None,即使该语句具有该值时无法到达。此外,它还抱怨命名风格,因为previous是一个常数,尽管最后一行有赋值

问题:是否有任何合适的pylint配置可以避免此类误报而不会引入同样明显的误报,如果是,为什么这不是默认配置

尝试的解决方案:禁用测试(导致假阴性)

例如,我可以通过创建一个包含pylint3 --generate-rcfile输出的$HOME/.pylintrc并对其进行编辑以将unsubscriptable-object添加到禁用测试列表中,从而完全抑制unsubscriptable-object警告(请参见第[MESSAGES CONTROL]disable=下的内容)

但是,如果我只是以这种方式禁用测试,然后验证以下代码:

"false negative"  # silence docstring warning (fair enough)

print(None[0])  # this line will fail

它告诉我:

$ pylint3 test2.py
Using config file /home/<myuser>/.pylintrc

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

因此,仅仅禁用测试并不是真正的答案

版本和平台信息

版本信息:

$ pylint3 --version
Using config file /home/<myuser>/.pylintrc
pylint3 1.8.3, 
astroid 1.6.0
Python 3.6.9 (default, Apr 18 2020, 01:56:04) 
[GCC 8.4.0]

平台:Ubuntu 18.04.4 LTS


Tags: 代码pytestnoneconfigobjectpylintword
1条回答
网友
1楼 · 发布于 2024-04-25 19:31:08

Pylint是一个静态类型检查器,具有该类型实用程序的所有限制。它不读懂你的思想,它只读懂你的代码。它的目的是告诉您可疑的代码,有时您必须告诉它忽略某些事情,因为您实际上希望以这种方式编写程序

如果你期望派林是一个完美的代码纳粹,识别你的每一个错误,永远不会忘乎所以,永远不会错过任何东西,你会失望的。如果您认为它是一个友好的观察者,可以在运行程序之前捕获您的一些错误,那么它是非常强大的。我认为这是一个必不可少的工具,只要你不要求太多。p>

你说previous不是一个常数,但这不是Pylint使用术语的方式。您在模块的最外层缩进级别声明previous,因此它是一个全局缩进;Pylint认为globals的唯一有效用法是as常量。因此出现了错误

要使pylint接受常量的任何格式,请在资源配置文件中使用此行:

const-rgx=[A-Za-z0-9_]{1,30}$

这就是我找到默认设置后所做的,即

const-naming-style=UPPER_CASE

太严格了

RC文件很重要,IMO。它允许您对Pylint的工作进行大量控制。如果您的RC文件名为pylint.RC,则使用 rcfile=pylint.rc标志调用pylint。根据环境的设置方式,您可能必须提供完整的路径名

根据所述配置,派林特毫无怨言地接受此代码:

previous = ''
for word in ['you', 'cannot', 'be', 'serious']:
    if previous:
        print(previous[0], word)
    previous = word

这是相同的逻辑,但更容易理解,因为它清楚地表明previous是一个字符串。因此Pylint确实帮助您编写了更可读的代码

有时也有必要告诉派林不要再抱怨某条线路了。在您的示例中,如果确实要将previous初始化为None,则只需添加一个内联pragma,如下所示:

previous = None
for word in ['you', 'cannot', 'be', 'serious']:
    if previous is not None:
        print(previous[0], word)   # pylint: disable=unsubscriptable-object
    previous = word

这是一个比您尝试的解决方案更好的解决方案,因为它仅在一行中失败错误,并且相同错误的其他事件将被标记

相关问题 更多 >