可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am running PyLint on a Python project. PyLint makes many complaints about being unable to find numpy members. How can I avoid this while avoiding skipping membership checks.
From the code:
import numpy as np
print np.zeros([1, 4])
Which, when ran, I get the expected:
[[ 0. 0. 0. 0.]]
However, pylint gives me this error:
E: 3, 6: Module 'numpy' has no 'zeros' member (no-member)
For versions, I am using pylint 1.0.0 (astroid 1.0.1, common 0.60.0) and trying to work with numpy 1.8.0 .
回答1:
If using Visual Studio Code with Don Jayamanne's excellent Python extension, add a user setting to whitelist numpy:
{
// whitelist numpy to remove lint errors
"python.linting.pylintArgs": [
"--extension-pkg-whitelist=numpy"
]
}
回答2:
I had the same issue here, even with the latest versions of all related packages (astroid 1.3.2
, logilab_common 0.63.2
, pylon 1.4.0
).
The following solution worked like a charm: I added numpy
to the list of ignored modules by modifying my pylintrc
file, in the [TYPECHECK]
section:
[TYPECHECK]
ignored-modules = numpy
Depending on the error, you might also need to add the following line (still in the [TYPECHECK] section
):
ignored-classes = numpy
回答3:
In recent versions of pylint you can add --extension-pkg-whitelist=numpy
to your pylint command. They had fixed this problem in an earlier version in an unsafe way. Now if you want them to look more carefully at a package outside of the standard library, you must explicitly whitelist it. See here.
回答4:
I was getting the same error for a small numpy project I was working on and decided that ignoring the numpy modules would do just fine. I created a .pylintrc
file with:
$ pylint --generate-rcfile > ~/.pylintrc
and following paduwan's and j_houg's advice I modified the following sectors:
[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
and
[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
and it "fixed" my issue.
回答5:
Since this is the top result in google and it gave me the impression that you have to ignore those warnings in all files:
The problem has actually been fixed in the sources of pylint/astroid last month https://bitbucket.org/logilab/astroid/commits/83d78af4866be5818f193360c78185e1008fd29e
but are not yet in the Ubuntu packages.
To get the sources, just
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
whereby the last step will most likely require a sudo
and of course you need mercurial to clone.
回答6:
There have been many different bugs reported about this over the past few years i.e. https://bitbucket.org/logilab/pylint/issue/58/false-positive-no-member-on-numpy-imports
I'd suggest disabling for the lines where the complaints occur.
# pylint: disable=E1103
print np.zeros([1, 4])
# pylint: enable=E1103
回答7:
For ignoring all the errors generated by numpy.core‘s attributes, we can now use:
$ pylint a.py --generated-members=numpy.*
As another solution, add this option to ~/.pylintrc or /etc/pylintrc file:
[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.*
For mentioned in question code by now this seems reduntant, but still matters for another modules, ie. netifaces and etc.
回答8:
Probably, it's confused with numpy's abstruse method of methods import. Namely, zeros
is in fact numpy.core.multiarray.zeros
, imported in numpy with statement
from .core import *
in turn imported with
from .numeric import *
and in numeric you'll find
zeros = multiarray.zeros
I guess I would be confused in place of PyLint!
See this bug for PyLint side of view.
回答9:
In Extension to j_hougs answer, you can now add the modules in question to this line in .pylintrc, which is already prepared empty on generation:
extension-pkg-whitelist=numpy
you can generate a sample .pylintrc by doing:
pylint --generate-rcfile > .pylintrc
and then edit the mentioned line
回答10:
This is the pseudo-solution I have come up with for this problem.
#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
Then, in your code, instead of calling numpy
functions as np.array
and np.zeros
and so on,
you would write np_array
, np_zeros
, etc.
Advantages of this approach vs. other approaches suggested in other answers:
- The pylint disable/enable is restricted to a small region of your code
- That means that you don't have to surround every single line that has an invocation of a numpy function with a pylint directive.
- You are not doing pylint disable of the error for your whole file, which might mask other issues with your code.
The clear disadvantage is that you have to explicitely import every numpy function you use.
The approach could be elaborated on further.
You could define your own module, call it say, numpy_importer
as follows
""" 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
Then, your application code could import this module only (instead of numpy) as
import numpy_importer as np
and use the names as usual: np.zeros
, np.array
etc.
The advantage of this is that you will have a single module in which all numpy
related imports are done once and for all, and then you import it with that single line, wherever you want. Still you have to be careful that numpy_importer
does not import names that don´t exist in numpy
as those errors won't be caught by pylint.
回答11:
This seems to work on at least Pylint 1.1.0:
[TYPECHECK]
ignored-classes=numpy
回答12:
This has finally been resolved in Pylint 1.8.2. Works out of the box, no pylintrc tweaks needed!
回答13:
I had this problem with numpy, scipy, sklearn, nipy, etc., and I solved it by wrapping epylint like so:
$ cat 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,
This script simply runs epylint, then scrapes its output to filter out false-positive warnings and errors. You can extend it by added more elif cases.
N.B.: If this applies to you, then you'll want to modify your pychechers.sh so it likes like this
#!/bin/bash
epylint.py "$1" 2>/dev/null
pyflakes "$1"
pep8 --ignore=E221,E701,E202 --repeat "$1"
true
(Of course, you have to make epylint.py executable first)
Here is a link to my .emacs https://github.com/dohmatob/mydotemacs. Hope this is useful to someone.
回答14:
I had to add this at the top of any file where I use numpy a lot.
# To ignore numpy errors:
# pylint: disable=E1101
Just in case someone in eclipse is having trouble with Pydev and pylint...
回答15:
A little bit of copy paste from the previous answer to summarize what is working (at least for me: debian-jessie)
In some older version of pylint
there was a problem preventing it working with numpy (and other similar packages).
Now that problem has been solved but external C packages (python interfaces to C code -like numpy-) are disabled by default for security reasons.
You can create a white list, to allow pylint
to use them in the file ~/.pylintrc
.
Basic command to run:
# ONLY if you do not already have a .pylintrc file in your home
$ pylint --generate-rcfile > .pylintrc
Then open the file and add the packages you want after extension-pkg-whitelist=
separated by comma. You can have the same behavior using the option --extension-pkg-whitelist=numpy
from the command line.
If you ignore some packages in the [TYPECHECK]
section that means that pylint
will never show error related to that packages. In practice, pylint
will not tell you anything about those packages.
回答16:
This solution worked for me
Basically, go to Select the gear icon from bottom left=>Setting=>Workspace Setting =>Extension=>Python Configuration=>Click on any Settings.json => add this in the file
"python.linting.pylintArgs" : [ "--extension-pkg-whitelist=numpy" ]
I am using VS 1.27.2
回答17:
I've been working on a patch to pylint to solve the issue with dynamic members in libraries such as numpy. It adds a "dynamic-modules" option which forces to check if members exist during runtime by making a real import of the module. See Issue #413 in logilab/pylint. There is also a pull request, see link in one of the comments.
回答18:
A quick answer: update Pylint to 1.7.1 (use conda-forge provided Pylint 1.7.1 if you use conda to manage packages)
I found a similar issue in pylint GitHub here and someone replied everything getting OK after updating to 1.7.1.
回答19:
I'm not sure if this is a solution, but in VSCode once I wrote explicitly in my user settings to enable pylint, all modules were recognized.
{
"python.linting.pep8Enabled": true,
"python.linting.pylintEnabled": true
}