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ć?

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.


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().


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

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

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.


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


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 :)


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.


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ł.


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).


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


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/")'

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)

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.


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).


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ę.


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

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



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.


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)


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

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.