PyLint Błąd „Unable to Import” - jak ustawić PYTHONPATH?

165

Używam PyLint z wnętrza Wing IDE w systemie Windows. Mam podkatalog (pakiet) w swoim projekcie i wewnątrz pakietu importuję moduł z najwyższego poziomu, tj.

__init__.py
myapp.py
one.py
subdir\
    __init__.py
    two.py

Wewnątrz two.pymam import onei to działa dobrze w czasie wykonywania, ponieważ katalog najwyższego poziomu (z którego myapp.pyjest uruchamiany) znajduje się w ścieżce Pythona. Jednak gdy uruchamiam PyLint na two.py, pojawia się błąd:

F0401: Unable to import 'one'

Jak to naprawić?

EMP
źródło

Odpowiedzi:

145

Są dwie opcje, o których wiem.

Po pierwsze, zmień PYTHONPATHzmienną środowiskową, aby zawierała katalog nad modułem.

Alternatywnie edytuj, ~/.pylintrcaby uwzględnić katalog nad modułem, na przykład:

[MASTER]
init-hook='import sys; sys.path.append("/path/to/root")'

(Lub w innej wersji pylint, hak init wymaga zmiany [Ogólne] na [MASTER])

Obie te opcje powinny działać.

Mam nadzieję, że to pomoże.

Brian M. Hunt
źródło
8
Ten hak pylint jest obecnie najlepszym sposobem w VScode, ponieważ PYTHONPATH nie jest jeszcze obsługiwany, ponieważ jest wbudowany w linter.
Danny Staple
2
Mam ten sam problem, używając MacVim z syntastic. Jak mogę skonfigurować prosektora, aby naprawił błąd importu?
Laurent
Powiązany post na blogu z kilkoma dodatkowymi szczegółami.
Christian Long
~/.pylintrcpracował dla mnie na OSX, drugi nie działał
Miquel
Nie jestem pewien, dlaczego nie jest to akceptowana odpowiedź - również, warto wspomnieć dla tych, którzy się na tym natkną, że trzeba, export PYTHONPATHżeby to pylintzobaczyli (przynajmniej w bash / zsh)
Marco Massenzio
43

Rozwiązanie do zmiany ścieżki w init-hookjest dobre, ale nie podoba mi się fakt, że musiałem tam dodać ścieżkę bezwzględną, w wyniku czego nie mogę udostępnić tego pliku pylintrc twórcom projektu. To rozwiązanie wykorzystujące ścieżkę względną do pliku pylintrc działa lepiej dla mnie:

[MASTER]
init-hook="from pylint.config import find_pylintrc; import os, sys; sys.path.append(os.path.dirname(find_pylintrc()))"

Zauważ, że pylint.config.PYLINTRCrównież istnieje i ma taką samą wartość jak find_pylintrc().

alex_koval
źródło
1
Potwierdzenie, że to naprawdę dostarczyło rozwiązanie dla błędów pylint E0611 i E0401. Dla użytkowników VSCode: Ważne jest, aby otwarty folder był „folderem głównym języka Python” i że plik .pylintrc znajduje się w tym folderze.
np8
upewnij się również, że żadna z nazw katalogów modułów nie zaczyna się od .(kropki).
Saw-mon i Natalie
2
jeśli chcesz dodać określony podfolder (tj. app) możesz użyćfrom pylint.config import find_pylintrc; import os, sys; sys.path.append(os.path.join(os.path.dirname(find_pylintrc()), 'app'))
chachan
27

1) sys.path to lista.

2) Czasami problem polega na tym, że sys.path nie jest twoją virtualenv.path i chcesz użyć pylint w swoim virtualenv

3) Tak jak powiedziałem, użyj haka init (zwróć uwagę na 'i "analiza pylint jest ścisła)

[Master]
init-hook='sys.path = ["/path/myapps/bin/", "/path/to/myapps/lib/python3.3/site-packages/", ... many paths here])'

lub

[Master]
init-hook='sys.path = list(); sys.path.append("/path/to/foo")'

.. i

pylint --rcfile /path/to/pylintrc /path/to/module.py
macm
źródło
8
Wydawało się, że naprawiłem to, instalując pylintw moim virtualenv zgodnie z tą radą: plaidzooks.tumblr.com/post/36813101879
Matt
3
To działa świetnie i powinno być najlepszą odpowiedzią. Jeśli nie masz zestawu .pylintrc, po prostu zrób to szybko pylint --generate-rcfile > .pylintrcw swoim folderze domowym.
reka18
26

Problem można rozwiązać, konfigurując ścieżkę pylint w venv: $ cat .vscode / settings.json

{
    "python.pythonPath": "venv/bin/python",
    "python.linting.pylintPath": "venv/bin/pylint"
}
jeanerpp
źródło
2
W przypadku systemu Windows to { "python.pythonPath": "${workspaceFolder}\\.venv\\Scripts\\python.exe" "python.linting.pylintPath": "${workspaceFolder}\\.venv\\Scripts\\pylint.exe" } tylko kompletność.
Roy2511
Pytanie nie dotyczy tego redaktora.
Ivailo Bardarov
VSCode wyświetla teraz ten komunikat: The setting "python.pythonPath" defined in your settings.json is now deprecated. Jeśli usunę python.pythonPathlinię, nadal wydaje się, że działa.
Jesse Aldridge
23

Czy masz pusty __init__.pyplik w obu katalogach, aby Python wiedział, że katalogi są modułami?

Podstawowy zarys, gdy nie korzystasz z folderu (tj. Może z pylinta, chociaż go nie używałem) to:

topdir\
  __init__.py
  functions_etc.py
  subdir\
    __init__.py
    other_functions.py

W ten sposób interpreter Pythona jest świadomy modułu bez odniesienia do aktualnego katalogu, więc jeśli pylint działa z własnej ścieżki bezwzględnej będzie w stanie uzyskać dostęp functions_etc.pyjako topdir.functions_etclub topdir.subdir.other_functions, jeżeli topdirjest na PYTHONPATH.

AKTUALIZACJA: Jeśli problemem nie jest __init__.pyplik, może po prostu spróbuj skopiować lub przenieść moduł do c:\Python26\Lib\site-packages- jest to typowe miejsce do umieszczania dodatkowych pakietów i na pewno będzie na twojej ścieżce python. Jeśli wiesz, jak tworzyć dowiązania symboliczne systemu Windows lub ich odpowiedniki (ja nie!), Możesz to zrobić zamiast tego. Dostępnych jest o wiele więcej opcji : http://docs.python.org/install/index.html , w tym opcja dołączania sys.path z katalogiem na poziomie użytkownika twojego kodu programistycznego, ale w praktyce zwykle po prostu łączę symbolicznie mój katalog rozwoju lokalnego do pakietów witryn - skopiowanie go ma ten sam efekt.

nieoprawny
źródło
1
Tak, mam __init__.pyw obu katalogach. Myślę, że problem polega na tym, że górny katalog NIE jest w PYTHONPATH, gdy PyLint działa i nie jestem pewien, jak to naprawić.
EMP
Łącze symboliczne to dobry pomysł, ale jest obsługiwany tylko w systemie Windows Vista i nowszych, a ja używam XP. Przypuszczam, że mógłbym spróbować połączyć go
EMP,
re hardlinking: Nie, lepiej tego nie rób. Bawiłem się tym i chociaż z pewnością działa (w pewnym sensie), nie będzie działać tak, jak się spodziewasz.
shylent
Linki symboliczne nie są dobrym pomysłem. To tylko rozwiązuje problem na twoim komputerze - gdy ktoś inny sprawdzi projekt, zostanie on dla niego uszkodzony.
Jonathan Hartley
12

ogólna odpowiedź na to pytanie, które znalazłem na tej stronie PROSZĘ NIE OTWIERAĆ, STRONA JEST ZAPŁEŻONA

utwórz .pylintrci dodaj

[MASTER]
init-hook="from pylint.config import find_pylintrc;
import os, sys; sys.path.append(os.path.dirname(find_pylintrc()))"
x-magix
źródło
5

Nie wiem, jak to działa z WingIDE, ale aby używać PyLint z Geany, ustawiłem moje zewnętrzne polecenie na:

PYTHONPATH=${PYTHONPATH}:$(dirname %d) pylint --output-format=parseable --reports=n "%f"

gdzie% f to nazwa pliku, a% d to ścieżka. Może się komuś przyda :)

Szymon
źródło
4

Musiałem zaktualizować PYTHONPATHzmienną systemową , aby dodać ścieżkę App Engine. W moim przypadku musiałem tylko wyedytować mój ~/.bashrcplik i dodać następujący wiersz:

export PYTHONPATH=$PYTHONPATH:/path/to/google_appengine_folder

W rzeczywistości próbowałem ustawić init-hookpierwszy, ale to nie rozwiązało problemu konsekwentnie w całej mojej bazie kodu (nie wiem, dlaczego). Po dodaniu go do ścieżki systemowej (prawdopodobnie ogólnie dobry pomysł) moje problemy zniknęły.

Brian Moeskau
źródło
3

Jedynym obejściem, które dopiero co odkryłem, jest uruchomienie PyLint dla całego pakietu, a nie pojedynczego pliku. W jakiś sposób udaje mu się wtedy znaleźć zaimportowany moduł.

EMP
źródło
Brzmi wspaniale; w jaki sposób?
Cees Timmerman,
1
@CeesTimmerman Uruchom pylint ... dirz folderu nadrzędnego. Wymaga __init__.pyto obecności w każdym podfolderze z .pyplikami.
yugr
3

Próbować

if __name__ == '__main__':
    from [whatever the name of your package is] import one
else:
    import one

Zwróć uwagę, że w Pythonie 3 składnia części w elseklauzuli wyglądałaby tak

from .. import one

Po namyśle to prawdopodobnie nie rozwiąże Twojego konkretnego problemu. Źle zrozumiałem pytanie i pomyślałem, że two.py jest uruchamiany jako główny moduł, ale tak nie jest. Biorąc pod uwagę różnice w sposobie, w jaki Python 2.6 (bez importowania absolute_importz __future__) i Python 3.x obsługuje importowanie, i tak nie musiałbyś tego robić dla Pythona 2.6, nie sądzę.

Jeśli jednak w końcu przejdziesz na Python 3 i planujesz używać modułu zarówno jako modułu pakietu, jak i samodzielnego skryptu wewnątrz pakietu, dobrym pomysłem może być zachowanie czegoś takiego jak

if __name__ == '__main__':
    from [whatever the name of your package is] import one   # assuming the package is in the current working directory or a subdirectory of PYTHONPATH
else:
    from .. import one

na myśli.

EDYCJA: A teraz możliwe rozwiązanie Twojego rzeczywistego problemu. Albo uruchom PyLint z katalogu zawierającego twój onemoduł (być może przez wiersz poleceń) lub umieść następujący kod gdzieś podczas uruchamiania PyLint:

import os

olddir = os.getcwd()
os.chdir([path_of_directory_containing_module_one])
import one
os.chdir(olddir)

Zasadniczo, jako alternatywa dla majstrowania przy PYTHONPATH, po prostu upewnij się, że bieżący katalog roboczy jest katalogiem zawierającym one.pypodczas importowania.

(Patrząc na odpowiedź Briana, prawdopodobnie mógłbyś przypisać poprzedni kod do init_hook, ale jeśli zamierzasz to zrobić, możesz po prostu dodać do sys.pathtego, co robi, co jest nieco bardziej eleganckie niż moje rozwiązanie).

UKŁUCIE
źródło
2

Kluczem jest dodanie katalogu projektu sys.pathbez rozważania o zmiennej env.

Dla kogoś, kto korzysta z VSCode, oto rozwiązanie jednowierszowe dla Ciebie, jeśli istnieje katalog podstawowy Twojego projektu:

[MASTER]
init-hook='base_dir="my_spider"; import sys,os,re; _re=re.search(r".+\/" + base_dir, os.getcwd()); project_dir = _re.group() if _re else os.path.join(os.getcwd(), base_dir); sys.path.append(project_dir)'

Pozwólcie, że trochę to wyjaśnię:

  • re.search(r".+\/" + base_dir, os.getcwd()).group(): znajdź katalog podstawowy zgodnie z plikiem edycji

  • os.path.join(os.getcwd(), base_dir): dodaj cwddo sys.pathśrodowiska wiersza poleceń


FYI, oto moje .pylintrc:

https://gist.github.com/chuyik/f0ffc41a6948b6c87c7160151ffe8c2f

chuyik
źródło
2

Miałem ten sam problem i naprawiłem go, instalując pylint w moim virtualenv, a następnie dodając plik .pylintrc do katalogu mojego projektu z następującym w pliku:

[Master]
init-hook='sys.path = list(); sys.path.append("./Lib/site-packages/")'
Nate
źródło
Muszę potwierdzić, że to pozbywa się błędów pylint E0611, ale błędy E0401 pozostają.
np8
1

Może ręcznie dołączając katalog w PYTHONPATH?

sys.path.append(dirname)
Mario Mikić
źródło
Hmm, ale gdzie umieściłbyś ten kod? Na górze każdego pliku? Przypuszczam, że to zadziała, ale to niezły hack tylko po to, aby PyLint działał.
EMP
@Evgeny: Zobacz odpowiedź, którą niedawno opublikował Brian M. Hunt.
JAB,
Dodanie tego na początku każdego pliku nie działa z jakiegoś powodu - PyLint wydaje się być całkowicie zadowolony z ignorowania wszelkich modyfikacji sys.path wykonanych w modułach, które skanuje. Jednak nie zadałem sobie trudu, aby
dowiedzieć się
1

Miałem ten sam problem, a ponieważ nie mogłem znaleźć odpowiedzi, mam nadzieję, że pomoże to każdemu, kto ma podobny problem.

Używam flymake z epylintem. Zasadniczo to, co zrobiłem, to dodanie haka dired-mode-hook, który sprawdza, czy katalog dired jest katalogiem pakietu Pythona. Jeśli tak, dodaję go do PYTHONPATH. W moim przypadku uważam katalog za pakiet Pythona, jeśli zawiera plik o nazwie „setup.py”.

;;;;;;;;;;;;;;;;;
;; PYTHON PATH ;;
;;;;;;;;;;;;;;;;;

(defun python-expand-path ()
  "Append a directory to the PYTHONPATH."
  (interactive
   (let ((string (read-directory-name 
          "Python package directory: " 
          nil 
          'my-history)))
     (setenv "PYTHONPATH" (concat (expand-file-name string)
                  (getenv ":PYTHONPATH"))))))

(defun pythonpath-dired-mode-hook ()
  (let ((setup_py (concat default-directory "setup.py"))
    (directory (expand-file-name default-directory)))
    ;;   (if (file-exists-p setup_py)
    (if (is-python-package-directory directory)
    (let ((pythonpath (concat (getenv "PYTHONPATH") ":" 
                  (expand-file-name directory))))
      (setenv "PYTHONPATH" pythonpath)
      (message (concat "PYTHONPATH=" (getenv "PYTHONPATH")))))))

(defun is-python-package-directory (directory)
  (let ((setup_py (concat directory "setup.py")))
    (file-exists-p setup_py)))

(add-hook 'dired-mode-hook 'pythonpath-dired-mode-hook)

Mam nadzieję że to pomoże.

user2826500
źródło
1

Jeśli ktoś szuka sposobu, aby uruchomić pylint jako zewnętrzne narzędzie w PyCharm i sprawić, by działał ze swoimi wirtualnymi środowiskami (dlaczego przyszedłem do tego pytania), oto jak to rozwiązałem:

  1. W PyCharm> Preferencje> Narzędzia> Narzędzia zewnętrzne, Dodaj lub edytuj element dla pylint.
  2. W ustawieniach narzędzia okna dialogowego Edytuj narzędzie ustaw Program tak, aby używał pylint z katalogu interpretera języka Python: $PyInterpreterDirectory$/pylint
  3. Ustaw inne parametry w polu Parametry, takie jak: --rcfile=$ProjectFileDir$/pylintrc -r n $FileDir$
  4. Ustaw katalog roboczy na $FileDir$

Teraz użycie pylint jako narzędzia zewnętrznego uruchomi pylint w dowolnym katalogu, który wybrałeś, używając wspólnego pliku konfiguracyjnego i użyje dowolnego interpretera skonfigurowanego dla twojego projektu (który prawdopodobnie jest twoim interpreterem virtualenv).

tterry
źródło
1

To jest stare pytanie, ale nie ma zaakceptowanej odpowiedzi, więc zasugeruję następujące: zmień instrukcję import w two.py, aby przeczytać:

from .. import one

W moim obecnym środowisku (Python 3.6, VSCode przy użyciu pylint 2.3.1) usuwa to oznaczoną instrukcję.

Mike C.
źródło
1

Znalazłem fajną odpowiedź . Edytuj swój pylintrc i dodaj następujące elementy w pliku master

init-hook="import imp, os; from pylint.config import find_pylintrc; imp.load_source('import_hook', os.path.join(os.path.dirname(find_pylintrc()), 'import_hook.py'))"
Devguru
źródło
1

Podczas instalowania Pythona możesz ustawić ścieżkę. Jeśli ścieżka jest już zdefiniowana, możesz zrobić w programie VS Code, naciśnij Ctrl + Shift + P i wpisz Python: Select Interpreter i wybierz zaktualizowaną wersję Pythona. Kliknij to łącze, aby uzyskać więcej informacji, https://code.visualstudio.com/docs/python/environments

Nadeem
źródło
0

jeśli używasz vscode, upewnij się, że katalog pakietu znajduje się poza katalogiem _pychache__.

Vikas Bhutani
źródło
Również w przypadku kodu VS wydaje się, że istnieją potencjalne problemy z kropką w nazwach folderów: github.com/PyCQA/pylint/issues/2182
Eric Burel
0

Jeśli używasz Cythona w Linuksie, rozwiązałem problem usunięcia module.cpython-XXm-X-linux-gnu.soplików w katalogu docelowym mojego projektu.

M. Andrade
źródło
0

po prostu dodaj ten kod w pliku .vscode / settings.json

, "python.linting.pylintPath": "venv / bin / pylint"

Spowoduje to powiadomienie o lokalizacji pylinta (który jest narzędziem do sprawdzania błędów dla Pythona)

user3395246
źródło
-1

Witam, udało mi się zaimportować pakiety z innego katalogu. Właśnie wykonałem następujące czynności: Uwaga: używam VScode

Kroki tworzenia pakietu w języku Python Praca z pakietami w języku Python jest naprawdę prosta. Wystarczy, że:

Utwórz katalog i nadaj mu nazwę swojego pakietu. Umieść w nim swoje zajęcia. Utwórz plik init .py w katalogu

Na przykład: masz folder o nazwie Framework, w którym przechowujesz wszystkie niestandardowe klasy, a Twoim zadaniem jest po prostu utworzenie pliku init .py w folderze o nazwie Framework.

Podczas importu musisz importować w ten sposób --->

z bazy importu Framework

więc błąd E0401 znika. Framework to folder, w którym właśnie utworzyłeś plik init .py, a baza to Twój niestandardowy moduł, do którego musisz zaimportować i pracować z nadzieją, że to pomaga !!!!

SUNEEL KAUSHIK S
źródło