如何让 Pylint 识别 NumPy 成员?

我在一个 Python 项目上运行 Pylint。Pylint 对无法找到 NumPy 成员提出了许多抱怨。我怎样才能在避免跳过会员检查的同时避免这种情况呢?

来自代码:

import numpy as np


print np.zeros([1, 4])

当我跑的时候,我得到了预期的结果:

[0.0.0.0. ]

然而,Pylint 给了我这个错误:

E: 3,6: 模块“ numpy”没有“0”成员(没有成员)

对于版本,我使用的是 Pylint 1.0.0(astroid 1.0.1,通用的0.60.0) ,并尝试使用 NumPy 1.8.0。

103062 次浏览

它可能与 NumPy 的方法导入的深奥方法混淆了。也就是说,zeros实际上是 numpy.core.multiarray.zeros,通过语句在 NumPy 中导入

from .core import *

依次进口

from .numeric import *

在数字中你会发现

zeros = multiarray.zeros

我想我会替皮林特感到困惑!

有关 Pylint 视图的侧面,请参见 这个窃听器

在过去的几年里,已经有很多关于这个的错误报告,比如 https://bitbucket.org/logilab/pylint/issue/58/false-positive-no-member-on-numpy-imports

我建议关闭投诉发生的线路。

# pylint: disable=E1103
print np.zeros([1, 4])
# pylint: enable=E1103

我遇到了 NumPy、 SciPy、 sklearn、 nipy 等等这些问题,我通过这样包裹电子线头来解决它:

文件 Epylint.py

#!/usr/bin/python


"""
Synopsis: epylint wrapper that filters a bunch of false-positive warnings and errors
Author: DOHMATOB Elvis Dopgima <gmdopp@gmail.com> <elvis.dohmatob@inria.fr>


"""


import os
import sys
import re
from subprocess import Popen, STDOUT, PIPE


NUMPY_HAS_NO_MEMBER = re.compile("Module 'numpy(?:\..+)?' has no '.+' member")
SCIPY_HAS_NO_MEMBER = re.compile("Module 'scipy(?:\..+)?' has no '.+' member")
SCIPY_HAS_NO_MEMBER2 = re.compile("No name '.+' in module 'scipy(?:\..+)?'")
NIPY_HAS_NO_MEMBER = re.compile("Module 'nipy(?:\..+)?' has no '.+' member")
SK_ATTR_DEFINED_OUTSIDE_INIT = re.compile("Attribute '.+_' defined outside __init__")
REL_IMPORT_SHOULD_BE = re.compile("Relative import '.+', should be '.+")
REDEFINING_NAME_FROM_OUTER_SCOPE = re.compile("Redefining name '.+' from outer scope")


if __name__ == "__main__":
basename = os.path.basename(sys.argv[1])
for line in Popen(['epylint', sys.argv[1], '--disable=C,R,I'  # filter thesew arnings
], stdout=PIPE, stderr=STDOUT, universal_newlines=True).stdout:
if line.startswith("***********"):
continue
elif line.startswith("No config file found,"):
continue
elif "anomalous-backslash-in-string," in line:
continue
if NUMPY_HAS_NO_MEMBER.search(line):
continue
if SCIPY_HAS_NO_MEMBER.search(line):
continue
if SCIPY_HAS_NO_MEMBER2.search(line):
continue
if "Used * or ** magic" in line:
continue
if "No module named" in line and "_flymake" in line:
continue
if SK_ATTR_DEFINED_OUTSIDE_INIT.search(line):
continue
if "Access to a protected member" in line:
continue
if REL_IMPORT_SHOULD_BE.search(line):
continue
if REDEFINING_NAME_FROM_OUTER_SCOPE.search(line):
continue
if NIPY_HAS_NO_MEMBER.search(line):
continue
# XXX extend by adding more handles for false-positives here
else:
print line,

这个脚本只是运行 epylint,然后擦除它的输出,以过滤出假阳性警告和错误。您可以通过添加更多的 elif 大小写来扩展它。

注意: 如果这适用于您,那么您需要修改 pychechers.sh,使其像这样

#!/bin/bash


epylint.py "$1" 2>/dev/null
pyflakes "$1"
pep8 --ignore=E221,E701,E202 --repeat "$1"
true

(当然,首先必须使 epylint.py 成为可执行文件。)

这里有一个到 my.emacs https://github.com/dohmatob/mydotemacs的链接。

我必须在任何经常使用 NumPy 的文件的顶部添加这个。

# To ignore numpy errors:
#     pylint: disable=E1101

万一有人在月食时遇到了皮德夫和皮林特的麻烦..。

这是我为这个问题想出的伪解。

#pylint: disable=no-name-in-module
from numpy import array as np_array, transpose as np_transpose, \
linspace as np_linspace, zeros as np_zeros
from numpy.random import uniform as random_uniform
#pylint: enable=no-name-in-module

然后,在您的代码中,不再像 np.arraynp.zeros那样调用 NumPy 函数,而是编写 np_arraynp_zeros等等。 这种方法相对于其他答案中建议的其他方法的优点:

  • Pylint 禁用/启用被限制在代码的一个小区域内
  • 这意味着您不必用 Pylint 指令包围调用 NumPy 函数的每一行。
  • 您没有对整个文件执行禁用该错误的 Pylint 操作,这可能会掩盖代码中的其他问题。

明显的缺点是必须显式导入所使用的每个 NumPy 函数。 这种方法可以进一步阐述。 您可以定义自己的模块,例如,按照以下方式调用 numpy_importer

""" module: numpy_importer.py
explicitely import numpy functions while avoiding Pylint errors
"""
#pylint: disable=unused-import
#pylint: disable=no-name-in-module
from numpy import array, transpose, zeros  #add all things you need
from numpy.random import uniform as random_uniform
#pylint: enable=no-name-in-module

然后,您的应用程序代码只能将此模块(而不是 NumPy)导入为

import numpy_importer as np

像往常一样使用名字: np.zerosnp.array等等。

这样做的好处是,您将拥有一个单独的模块,在该模块中,所有与 NumPy 相关的导入都将一劳永逸地完成,然后您可以随时随地用这一行导入。但是您仍然必须小心,因为这些错误不会被 Pylint 捕获,所以 numpy_importer不会导入 NumPy 中不存在的名称。

因为这是谷歌搜索的最高结果,它给我的印象是,你必须忽略所有文件中的警告:

这个问题实际上已经在 Pylint/astroid 上个月的 https://bitbucket.org/logilab/astroid/commits/83d78af4866be5818f193360c78185e1008fd29e 中得到解决 但是还没有包含在 Ubuntu 包中。

为了得到消息来源

hg clone https://bitbucket.org/logilab/pylint/
hg clone https://bitbucket.org/logilab/astroid
mkdir logilab && touch logilab/__init__.py
hg clone http://hg.logilab.org/logilab/common logilab/common
cd pylint && python setup.py install

因此最后一步很可能需要 sudo,当然还需要 Mercurial 来克隆。

我一直在开发一个到 Pylint 的补丁,用图书馆中的动态成员(比如 NumPy)来解决这个问题。

它添加了一个“动态模块”选项,强制在运行时通过实际导入模块来检查成员是否存在。参见 Logilab/pylint 中的第413期。还有一个 pull 请求; 请参见注释中的链接。

我在这里遇到了同样的问题,即使是所有相关软件包的最新版本(astroid 1.3.2logilab_common 0.63.2pylon 1.4.0)。

下面的解决方案非常有效: 通过修改 [TYPECHECK]部分中的 pylintrc文件,我将 numpy添加到被忽略的模块列表中:

[TYPECHECK]


ignored-modules = numpy

根据错误,您可能还需要添加以下代码行(仍然在 [TYPECHECK] section中) :

ignored-classes = numpy

在最新版本的 Pylint 中,您可以将 --extension-pkg-whitelist=numpy添加到您的 Pylint 命令中。

他们以一种不安全的方式在早期版本中解决了这个问题。现在,如果您想让他们更仔细地查看标准库之外的包,就必须显式地将其列入白名单。看这里.

至少在 Pylint1.1.0中是这样的:

[TYPECHECK]


ignored-classes=numpy

我在一个小的 NumPy 项目中得到了同样的错误,我认为忽略 NumPy 模块就可以了。我创建了一个 .pylintrc文件:

$ pylint --generate-rcfile > ~/.pylintrc

根据 Paduwan 餐厅J _ houg’s的建议,我修改了以下部分:

[MASTER]


# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
extension-pkg-whitelist=numpy

还有

[TYPECHECK]


# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=numpy


# List of classes names for which member attributes should not be checked
# (useful for classes with attributes dynamically set). This supports can work
# with qualified names.
ignored-classes=numpy

它“解决”了我的问题。

分机请回答中,现在可以将有问题的模块添加到。Pylintrc,在发电时就已经准备好了:

extension-pkg-whitelist=numpy

您可以通过以下操作生成一个 sample.pylintrc:

pylint --generate-rcfile > .pylintrc

然后编辑提到的行。

如果使用 VisualStudio 代码和 Don Jayamanne 的优秀的 Python 扩展,添加一个用户设置到白名单 NumPy:

{
// Whitelist NumPy to remove lint errors
"python.linting.pylintArgs": [
"--extension-pkg-whitelist=numpy"
]
}

从前面的答案复制一点粘贴来总结什么是工作(至少对我来说: Debian 8(Jessie))

  1. 在某些旧版本的 Pylint 中,有一个问题阻止它使用 NumPy (和其他类似的包)。

  2. 现在这个问题已经解决了,但出于安全原因,默认情况下禁用了外部 C 包(Python 对 C 代码的接口,如 NumPy -)。

  3. 您可以创建一个白名单,以允许 Pylint 在文件 ~/.pylintrc中使用它们。

要运行的基本命令:

# ONLY if you do not already have a .pylintrc file in your home
$ pylint --generate-rcfile > .pylintrc

然后打开该文件,并在 extension-pkg-whitelist=之后添加所需的包,用逗号分隔。可以使用命令行中的选项 --extension-pkg-whitelist=numpy来实现相同的行为。

如果忽略 [TYPECHECK]部分中的某些包,这意味着 Pylint 将永远不会显示与这些包相关的错误。实际上,Pylint 不会告诉您关于这些包的任何信息。

快速回答: 将 Pylint 更新为1.7.1(如果使用 康达管理包,请使用 Conda-forge 提供的 Pylint 1.7.1)。

我在 我是 Pylint GitHub中发现了类似的问题,有人在更新到1.7.1后回复说一切正常。

为了忽略 numpy.core 属性生成的所有错误,我们现在可以使用:

$ pylint a.py --generated-members=numpy.*

作为另一种解决方案,将此选项添加到 ~/. pylintrc/etc/pylintrc文件:

[TYPECHECK]


# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=numpy.*

这个 特写是在 PyLint 1.6.0中引入的。应该注意的是,来自原始问题的代码片段甚至在没有任何其他设置的情况下通过了这个版本的链接。然而,这在更复杂的情况下是有用的。

我不确定这是否是一个解决方案,但是在 Visual Studio Code 中,一旦我在用户设置中显式地编写了启用 Pylint 的代码,所有模块都会被识别。

{
"python.linting.pep8Enabled": true,
"python.linting.pylintEnabled": true
}

这个问题最终在 Pylint 1.8.2中得到了解决!

这个办法对我很有效。

基本上,从左下角到 选择的齿轮图标→ 设定工作空间设置分机Python 配置→点击任何 设置 json→添加到文件中 “ python.linting. pylintArgs”: [“—— ext- pkg-whitelist = numpy”]

我正在使用 VisualStudio 代码1.27.2。

如果您不想添加更多的配置,请将此代码添加到您的配置文件,而不是“白名单”。

{
"python.linting.pylintArgs": ["--generate-members"],
}

最近(因为在 斯派德或 Pylint 或? 中发生了变化),我已经得到了 E1101错误(“没有成员”)从 Spyder 的静态程序分析占星术。常量符号。我不知道为什么。

对于 Linux 或 Unix 系统上的所有用户(Mac 可能类似) ,我的简单解决方案是创建一个 /etc/pylintrc文件,如下所示:

[TYPECHECK]
ignored-modules=astropy.constants

当然,这可以放在一个个人的 $主页/. pylintrc文件中,而且,我可以更新一个现有的文件。

我在使用另一个模块(kivy.properties)时遇到了同样的问题,它是一个类似 NumPy 的封装的 C 模块。

使用 Visual Studio Code V1.38.0,接受的解决方案停止了项目的所有 linting。因此,虽然它确实移除了假阳性的 no-name-in-module,但并没有真正改善情况。

对我来说,最好的解决办法是在有问题的模块上使用 --ignored-modules参数。麻烦的是,通过 python.linting.pylintArgs传递任何参数都会消除 默认的 VisualStudio 代码设置,因此您也需要重置它们。这给我留下了以下 设置 json文件:

{
"python.pythonPath": "C:\\Python\\Python37\\python.exe",
"python.linting.pylintEnabled": true,
"python.linting.enabled": true,
"python.linting.pylintArgs": [
"--ignored-modules=kivy.properties",
"--disable=all",
"--enable=F,E,unreachable,duplicate-key,unnecessary-semicolon,global-variable-not-assigned,unused-variable,binary-op-exception,bad-format-string,anomalous-backslash-in-string,bad-open-mode"
]
}

这是一个带有 生成成员的旧窃听器。如果使用 麻木不仁以外的另一个名称,如 没有,那么必须将其添加到 Pylint 配置中(空格或逗号分隔——无论如何) ,因为 Pylint 不能识别这一点。它应该是这样的:

[pylint]
generated-members=numpy.*,np.*,foo.*

它甚至在无成员错误中抛出一个完整路径,但表达式需要精确。这是一个老错误,似乎很快就会修复。检查 Logilab/pylint 中的问题 # 2498