Jak sprawić, by PyLint rozpoznawał członków numpy?


163

Używam PyLint w projekcie Pythona. PyLint skarży się na niemożność znalezienia tępych członków. Jak mogę tego uniknąć, unikając pomijania sprawdzania członkostwa.

Z kodu:

import numpy as np

print np.zeros([1, 4])

Które po uruchomieniu otrzymuję oczekiwane:

[[0. 0. 0. 0.]]

Jednak pylint daje mi ten błąd:

E: 3, 6: Moduł „numpy” nie ma elementu „zera” (brak elementu)

W przypadku wersji używam pylint 1.0.0 (astroid 1.0.1, wspólny 0.60.0) i próbuję pracować z numpy 1.8.0.

Odpowiedzi:


75

Jeśli używasz programu Visual Studio Code z doskonałym rozszerzeniem Pythona Dona Jayamanne'a , dodaj ustawienie użytkownika do białej listy numpy:

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

2
To pomogło! na VSCode 1.12.2 potwierdził, że działa na Windows 10 x64.
Simara

8
Potrzebowałem więcej: "python.linting.pylintArgs": ["--ignored-modules = numpy", "--ignored-classes = numpy", "--extension-pkg-whitelist = numpy"]
Piotr

2
Rozwiązanie @Peter działające w systemie Windows 7 x64 i Visual Studio Code 1.15.1 !!
BSP

3
@BSP Post Petera nie rozwiązuje problemu, ignoruje go. Gdybym mógł odrzucić ten komentarz, zrobiłbym to ...
Jonathan H

4
To już nie działa z pylint 2.3.0.
Guillochon

58

Miałem ten sam problem tutaj, nawet z najnowszych wersji wszystkich pakietów powiązanych ( astroid 1.3.2, logilab_common 0.63.2, pylon 1.4.0).

Następujące rozwiązanie działało jak urok: dodałem numpydo listy ignorowanych modułów, modyfikując mój pylintrcplik, w [TYPECHECK]sekcji:

[TYPECHECK]

ignored-modules = numpy

W zależności od błędu może być również konieczne dodanie następującego wiersza (nadal w [TYPECHECK] section):

ignored-classes = numpy

2
W Linuksie z pylint 1.4.4, astroid 1.3.8 i Python 3.4.3 to zadziałało, ale musiałem umieścić extension-pkg-whitelist=numpylinię pod [MASTER]nagłówkiem pliku .pylintrc. pylint wydaje się być dość kruchym oprogramowaniem i wymaga dotyku eksperta, aby działał przy podstawowych zadaniach.
Eric Leschinski

12
To nie jest dobre rozwiązanie. Wszystko, co robi, to całkowicie wyłączyć sprawdzanie pylinta pod kątem istnienia jakichkolwiek członków. Idealnie byłoby, gdybyś prawidłowo je rozpoznawał, co robią inne rozwiązania.
iFreilicht

1
@iFreilicht To środek bezpieczeństwa. W czasie wykonywania definicje modułów mogą zmieniać się dynamicznie; ale włączenie tego w pylint wymagałoby uruchomienia dowolnego kodu. Niemniej jednak nadal oczekiwałbym jakiejś notatki w odpowiedzi o tym --extension-pkg-whitelist, który faktycznie wykonuje import dla określonego modułu.
Zev Spitz

43

Otrzymałem ten sam błąd dla małego projektu numpy, nad którym pracowałem i zdecydowałem, że ignorowanie modułów numpy wystarczy. Utworzyłem .pylintrcplik z:

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

i zgodnie z radą paduwana i j_houga zmodyfikowałem następujące sektory:

[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

i

[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

i to „naprawiło” mój problem.


6
Czy na pewno musiałeś dodać go również do dwóch ignored-*wejść? Dla mnie samo dodanie modułu do białej listy rozszerzeń działa idealnie.
iFreilicht

39

W najnowszych wersjach pylint możesz dodać --extension-pkg-whitelist=numpydo swojego polecenia pylint. Naprawili ten problem we wcześniejszej wersji w niebezpieczny sposób. Teraz, jeśli chcesz, aby uważniej przyjrzeli się pakietowi spoza biblioteki standardowej, musisz wyraźnie dodać go do białej listy. Spójrz tutaj.


2
Link „Zobacz tutaj” nie działa. Rozwiązanie wciąż jednak działa, po prostu trudno zrozumieć, dlaczego. Byłoby miło dodać fragment powiązanego numeru.
GergelyPolonkai

Link „Zobacz tutaj” został naprawiony (odwołuje się teraz do tego samego problemu na githubie)
David Clarke

Wygląda na to, że działa dla modułów i pakietów, ale nie nazw klas.
Ian A. Mason

17

Skoro to najwyższy wynik w google i sprawiło to wrażenie, że trzeba ignorować te ostrzeżenia we wszystkich plikach:

Problem został faktycznie naprawiony w źródłach pylint / astroid w zeszłym miesiącu https://bitbucket.org/logilab/astroid/commits/83d78af4866be5818f193360c78185e1008fd29e, ale nie ma ich jeszcze w pakietach Ubuntu.

Aby zdobyć źródła, po prostu

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

przy czym ostatni krok najprawdopodobniej będzie wymagał sudoi oczywiście do sklonowania potrzebujesz rtęci.


Powiedziałbym, że nie musisz klonować nowego logilab / common, ale musisz zainstalować nowy logilab / astroid. Ponowna instalacja programów logilab / astroid i logilab / pylint rozwiązuje problem za mnie.
paugier

7
Z jakich wersji korzystacie? Jestem na astroidzie 1.3.2 i pylint 1.4.0 i nadal mam problem z tym kodem, w from numpy import ceilwyniku E: 1, 0: No name 'ceil' in module 'numpy' (no-name-in-module) którego sprawdziłem zatwierdzenie, o którym mowa powyżej i wygląda na to, że te zmiany są w wersji astroida, którą mam.
Zach Dwiel

2
Zrobił dokładnie tak, jak zasugerowano na Xubuntu 14.04, a to spowodowało niedziałający pylint: py2.7.egg / pylint / lint.py ", wiersz 866, w check_astroid_module astroid.close () AttributeError: 'Module' object has no attribute ' close '
bli

3
Być może jest to regresja - wydaje się, że pojawiła się wersja, która ma rozwiązać problem. Tak czy inaczej, otworzyłem nowy numer na ten temat na bitbucket.org/logilab/pylint/issue/453/ ...
dstromberg

4
Najwyraźniej nadal nie jest to naprawione w pylint 1.4.2, astroid 1.3.4: Module 'numpy' has no 'zeros' member (no-member)
Bill

12

Aby zignorować wszystkie błędy generowane przez atrybuty numpy.core, możemy teraz użyć:

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

Jako inne rozwiązanie dodaj tę opcję do pliku ~ / .pylintrc lub / 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.*

Dla wspomnianego w pytaniu kodu na razie wydaje się to zbędne, ale nadal ma znaczenie dla innych modułów, tj. netifaces itp.


Miałem ten sam problem podczas używania patsy.dmatrices. Dodanie generated-members=patsy.dmatricesrozwiązało mój problem.
Jonas Dahlbæk

12

Jeśli nie chcesz dodawać więcej konfiguracji, dodaj ten kod do pliku konfiguracyjnego zamiast „białej listy”.

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

9
Należy wspomnieć, że odnosi się to bardzo konkretnie do VS Code.
bers

To wyjdziepylint: error: no such option: --generate-members
Spaceship222

8

W ciągu ostatnich kilku lat zgłoszono wiele różnych błędów, np. Https://bitbucket.org/logilab/pylint/issue/58/false-positive-no-member-on-numpy-imports

Sugerowałbym wyłączenie dla linii, w których występują reklamacje.

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

10
Używam numpy tak często, że równie dobrze mógłbym po prostu wyłączyć sprawdzanie braku członków w całym pliku, jednak chcę tego uniknąć.
Alphadelta

2
-1 Tylko dlatego, że odpowiedź @ bijancn powinna teraz zastąpić tę.
LondonRob

@LondonRob jednak nie. Problem nadal występuje w 1.4.2. Rozwiązanie paduwan jest lepsze, ponieważ nie wymaga dodawania hacky cruft do twojego kodu.
naught101

7

Prawdopodobnie jest mylony z zawiłą metodą importu metod Numpy. Mianowicie zerosjest w rzeczywistości numpy.core.multiarray.zerosimportowany w numpy z instrukcją

from .core import *

z kolei importowane z

from .numeric import *

i liczbowo znajdziesz

zeros = multiarray.zeros

Chyba byłbym zdezorientowany na miejscu PyLint!

Zobacz ten błąd dla strony widoku PyLint.


Chciałbym móc importować pojedyncze metody, takie jak ta, ale używam zbyt wielu funkcji i spowodowałoby to ogromny bałagan.
Alphadelta

@ Alphadelta14 Nawet znalezienie ich wszystkich byłoby wielkim bałaganem. Zobacz sugestię w linku na końcu mojej odpowiedzi.
alko

2
To łącze SO sprawia, że ​​PyLint ignoruje importowanie niektórych modułów. Nie jestem pewien, czy spowodowałoby to usunięcie błędów braku elementu członkowskiego dla tych plików. Chciałbym również w miarę możliwości uniknąć łatania mojego PyLint.
Alphadelta

@ Alphadelta14 Myślę, że w takim razie powinieneś poczekać na poprawkę do PyLint.
alko

4

Musiałem dodać to na początku każdego pliku, w którym często używam numpy.

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

Na wypadek gdyby ktoś w zaćmieniu miał kłopoty z Pydevem i pylintem ...


4

W rozszerzeniu odpowiedzi j_hougs możesz teraz dodać omawiane moduły do ​​tej linii w pliku .pylintrc, który jest już przygotowany pusty przy generowaniu:

extension-pkg-whitelist=numpy

możesz wygenerować przykładowy plik .pylintrc, wykonując:

pylint --generate-rcfile > .pylintrc

a następnie edytuj wspomnianą linię


4

Zostało to ostatecznie rozwiązane w Pylint 1.8.2. Działa po wyjęciu z pudełka, nie są potrzebne żadne poprawki pylintrc!


3

To jest pseudo-rozwiązanie, które wymyśliłem dla tego problemu.

#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

Następnie w kodzie, zamiast wywoływania numpyfunkcji, jak np.arrayi np.zerosi tak dalej, to napisze np_array, np_zerositp Zalety takiego podejścia wobec innych rozwiązań proponowanych w innych odpowiedzi:

  • Włączanie / wyłączanie pylinta jest ograniczone do małego regionu twojego kodu
  • Oznacza to, że nie musisz otaczać każdej pojedynczej linii, która ma wywołanie funkcji numpy, dyrektywą pylint.
  • Nie robisz pylint wyłączania błędu dla całego pliku, co może maskować inne problemy z kodem.

Oczywistą wadą jest to, że musisz jawnie zaimportować każdą używaną funkcję numpy. Podejście to można by rozwinąć dalej. Możesz zdefiniować swój własny moduł, nazwij go, powiedzmy, numpy_importerw następujący sposób

""" 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

Wtedy twój kod aplikacji może importować tylko ten moduł (zamiast numpy) jako

import numpy_importer as np 

i używać nazw jak zwykle: np.zeros, np.arrayetc.

Zaletą tego jest to, że będziesz mieć pojedynczy moduł, w którym wszystkie numpypowiązane importy są wykonywane raz na zawsze, a następnie importujesz je za pomocą tej pojedynczej linii, gdziekolwiek chcesz. Mimo to musisz uważać, aby numpy_importernie importować nazw, których nie ma w programie, numpyponieważ te błędy nie zostaną przechwycone przez pylint.


2

Miałem ten problem z numpy, scipy, sklearn, nipy itp. I rozwiązałem go, owijając epylint tak:

$ 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,

Ten skrypt po prostu uruchamia epylint, a następnie przetwarza dane wyjściowe, aby odfiltrować fałszywie dodatnie ostrzeżenia i błędy. Możesz go przedłużyć, dodając więcej przypadków elif.

NB: Jeśli to dotyczy Ciebie, będziesz chciał zmodyfikować swój plik pychechers.sh, aby tak się podobał

#!/bin/bash

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

(Oczywiście musisz najpierw stworzyć plik wykonywalny epylint.py)

Oto link do mojego .emacs https://github.com/dohmatob/mydotemacs . Mam nadzieję, że to komuś się przyda.


2

Wydaje się, że działa przynajmniej na Pylint 1.1.0:

[TYPECHECK]

ignored-classes=numpy

2

To rozwiązanie zadziałało dla mnie

Zasadniczo przejdź do Wybierz ikonę koła zębatego od dołu po lewej stronie => Ustawienia => Ustawienia obszaru roboczego => Rozszerzenie => Konfiguracja Pythona => Kliknij dowolne Ustawienia.json => dodaj to w pliku "python.linting.pylintArgs": [" --extension-pkg-whitelist = numpy "] Używam VS 1.27.2


2

Że ten sam problem z innym modułem ( kivy.properties), który jest owinięty moduł C podobne numpy.

Przy użyciu VSCode V1.38.0 zaakceptowane rozwiązanie zatrzymało wszystkie linting dla projektu. Tak więc, chociaż rzeczywiście usunął fałszywie dodatni wynik no-name-in-module, tak naprawdę nie poprawił sytuacji.

Najlepszym rozwiązaniem dla mnie było użycie --ignored-modulesargumentu w module powodującym naruszenie. Problem polega na tym, przechodząc żadnego argumentu poprzez python.linting.pylintArgsociera się o ustawieniach domyślnych VSCode , więc trzeba ponownie ustawić te również. To pozostawiło mi następujący plik settings.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"
    ]
}

"python.linting.pylintArgs": ["--generate-members = kivy.properties"]
yee

1

Trochę kopiuj wklej z poprzedniej odpowiedzi, aby podsumować, co działa (przynajmniej dla mnie: debian-jessie)

  1. W niektórych starszych wersjach pylintwystępował problem uniemożliwiający pracę z numpy (i innymi podobnymi pakietami).

  2. Teraz ten problem został rozwiązany, ale zewnętrzne pakiety C (interfejsy Pythona do kodu C - podobnie jak numpy-) są domyślnie wyłączone ze względów bezpieczeństwa.

  3. Możesz utworzyć białą listę, aby umożliwić pylintużycie ich w pliku ~/.pylintrc.

Podstawowe polecenie do uruchomienia: # TYLKO jeśli nie masz jeszcze pliku .pylintrc w swoim domu $ pylint --generate-rcfile> .pylintrc

Następnie otwórz plik i dodaj żądane pakiety, extension-pkg-whitelist=oddzielając je przecinkami. Możesz mieć to samo zachowanie, używając opcji --extension-pkg-whitelist=numpyz wiersza poleceń.

Jeśli zignorujesz niektóre pakiety w [TYPECHECK]sekcji, oznacza to, że pylintnigdy nie pokażą błędów związanych z tymi pakietami. W praktyce pylintnie powie Ci nic o tych pakietach.


0

Pracowałem nad poprawką do pylint, aby rozwiązać problem z dynamicznymi członkami w bibliotekach, takich jak numpy. Dodaje opcję „dynamiczne-moduły”, która wymusza sprawdzenie, czy elementy członkowskie istnieją w czasie wykonywania, dokonując rzeczywistego importu modułu. Zobacz wydanie nr 413 w logilab / pylint . Istnieje również żądanie ściągnięcia, patrz link w jednym z komentarzy.


Oto jak rozwiązuje to pydev (specjalna lista modułów do sprawdzenia wczytywania). Jak tam praca?
Epu

0

Szybka odpowiedź: zaktualizuj Pylint do 1.7.1 (użyj conda-forge dostarczonego Pylint 1.7.1, jeśli używasz conda do zarządzania pakietami)

Znalazłem podobny problem w pylint GitHub tutaj i ktoś odpowiedział, że wszystko jest w porządku po aktualizacji do 1.7.1.


0

Nie jestem pewien, czy jest to rozwiązanie, ale w VSCode, gdy napisałem wyraźnie w ustawieniach użytkownika, aby włączyć pylint, wszystkie moduły zostały rozpoznane.

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

0

Ostatnio (odkąd coś się zmieniło w spyder lub pylint czy?), Otrzymuję błędy E1101 („brak członka”) z analizy statycznego kodu Spydera na symbolach astropy.constants. Nie mam pojęcia dlaczego.

Moim uproszczonym rozwiązaniem dla wszystkich użytkowników systemu Linux lub Unix (Mac jest prawdopodobnie podobny) jest utworzenie pliku / etc / pylintrc w następujący sposób:

[TYPECHECK]
ignored-modules=astropy.constants

Oczywiście można to zamiast tego umieścić w osobistym pliku $ HOME / .pylintrc. Mogłem zaktualizować istniejący plik.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.