PyLint-Fehler "Import nicht möglich" - wie wird PYTHONPATH eingestellt?

164

Ich führe PyLint in Wing IDE unter Windows aus. Ich habe ein Unterverzeichnis (Paket) in meinem Projekt und innerhalb des Pakets importiere ich ein Modul von der obersten Ebene, dh.

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

Im Inneren habe two.pyich import oneund dies funktioniert gut zur Laufzeit, da sich das Verzeichnis der obersten Ebene (von dem aus ausgeführt myapp.pywird) im Python-Pfad befindet. Wenn ich PyLint jedoch auf two.py ausführe, wird ein Fehler angezeigt:

F0401: Unable to import 'one'

Wie behebe ich das?

EMP
quelle

Antworten:

144

Mir sind zwei Optionen bekannt.

Ändern Sie zunächst die PYTHONPATHUmgebungsvariable so, dass sie das Verzeichnis über Ihrem Modul enthält.

Alternativ ~/.pylintrckönnen Sie das Verzeichnis über Ihrem Modul wie folgt bearbeiten :

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

(Oder in einer anderen Version von Pylint müssen Sie für den Init-Hook [General] in [MASTER] ändern.)

Beide Optionen sollten funktionieren.

Hoffentlich hilft das.

Brian M. Hunt
quelle
8
Dieser Pylint-Haken ist derzeit der beste Weg in VScode, da PYTHONPATH noch nicht unterstützt wird, da es in der Verwendung von Linter eingebaut ist.
Danny Staple
2
Ich habe das gleiche Problem mit MacVim mit Syntastic. Wie kann ich Prosector konfigurieren, um den Importfehler zu beheben?
Laurent
Verwandter Blog-Beitrag mit ein paar weiteren Details.
Christian Long
~/.pylintrcarbeitete für mich unter OSX, der andere funktionierte nicht
Miquel
Ich bin mir nicht sicher, warum dies nicht die akzeptierte Antwort ist - auch erwähnenswert für diejenigen, die darüber stolpern, dass Sie dies export PYTHONPATHtun müssen, damit sie pylintes sehen (zumindest in bash / zsh)
Marco Massenzio
41

Die Lösung zum Ändern des Pfads init-hookist gut, aber ich mag die Tatsache nicht, dass ich dort einen absoluten Pfad hinzufügen musste, da ich diese pylintrc-Datei nicht für die Entwickler des Projekts freigeben kann. Diese Lösung mit dem relativen Pfad zur pylintrc-Datei funktioniert für mich besser:

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

Beachten Sie, dass pylint.config.PYLINTRCauch vorhanden ist und den gleichen Wert wie hat find_pylintrc().

alex_koval
quelle
1
Bestätigen, dass dies wirklich die Lösung für E0611- und E0401-Pylint-Fehler lieferte. Für VSCode-Benutzer: Es ist wichtig, dass der geöffnete Ordner der "Python-Stammordner" ist und dass sich die .pylintrc in diesem Ordner befindet.
np8
Stellen Sie außerdem sicher, dass keiner Ihrer Modulverzeichnisnamen mit .(Punkt) beginnt .
Saw-mon und Natalie
2
Wenn Sie einen bestimmten Unterordner (dh app) hinzufügen möchten, können Sie verwendenfrom 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 ist eine Liste.

2) Das Problem ist manchmal, dass der sys.path nicht Ihr virtualenv.path ist und Sie pylint in Ihrem virtualenv verwenden möchten

3) Verwenden Sie wie gesagt init-hook (achten Sie auf 'und "die Analyse von Pylint ist streng)

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

oder

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

.. und

pylint --rcfile /path/to/pylintrc /path/to/module.py
macm
quelle
8
Ich schien dies behoben zu haben, indem pylintich es gemäß diesem Rat in meine virtuelle Umgebung installierte : plaidzooks.tumblr.com/post/36813101879
Matt
3
Dies funktioniert hervorragend und sollte die beste Antwort sein. Wenn Sie kein .pylintrc-Set haben, stellen Sie einfach sicher, dass Sie dies schnell pylint --generate-rcfile > .pylintrcin Ihrem Home-Ordner tun .
reka18
26

Das Problem kann gelöst werden, indem der Pylint-Pfad unter venv: $ cat .vscode / settings.json konfiguriert wird

{
    "python.pythonPath": "venv/bin/python",
    "python.linting.pylintPath": "venv/bin/pylint"
}
jeanerpp
quelle
2
Für Windows ist es { "python.pythonPath": "${workspaceFolder}\\.venv\\Scripts\\python.exe" "python.linting.pylintPath": "${workspaceFolder}\\.venv\\Scripts\\pylint.exe" } nur der Vollständigkeit halber.
Roy2511
Die Frage stellen Sie nicht für diesen Editor.
Ivailo Bardarov
VSCode zeigt jetzt folgende Meldung an: The setting "python.pythonPath" defined in your settings.json is now deprecated. Wenn ich die python.pythonPathZeile lösche, scheint sie trotzdem zu funktionieren.
Jesse Aldridge
23

Haben Sie eine leere __init__.pyDatei in beiden Verzeichnissen, um Python wissen zu lassen, dass die Verzeichnisse Module sind?

Die grundlegende Gliederung, wenn Sie nicht aus dem Ordner heraus ausgeführt werden (dh möglicherweise von Pylint, obwohl ich das nicht verwendet habe), lautet:

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

Dies ist , wie das Python - Interpreter kennt das Modul ohne Bezug auf das aktuelle Verzeichnis, so dass , wenn Pylint aus seinem eigenen absoluten Pfad ausgeführt wird , um den Zugang der Lage sein , functions_etc.pywie topdir.functions_etcoder topdir.subdir.other_functions, sofern topdirauf die istPYTHONPATH .

UPDATE: Wenn das Problem nicht die __init__.pyDatei ist, versuchen Sie vielleicht einfach, Ihr Modul zu kopieren oder zu verschieben c:\Python26\Lib\site-packages- dies ist ein üblicher Ort, um zusätzliche Pakete zu platzieren, und befindet sich definitiv auf Ihrem Pythonpfad. Wenn Sie wissen, wie man symbolische Windows-Links oder ähnliches erstellt (ich nicht!), Können Sie dies stattdessen tun. Hier gibt es viele weitere Optionen : http://docs.python.org/install/index.html , einschließlich der Option, sys.path an das Verzeichnis auf Benutzerebene Ihres Entwicklungscodes anzuhängen, aber in der Praxis verlinke ich normalerweise nur symbolisch Mein lokales Entwicklungsverzeichnis für Site-Pakete - das Kopieren hat den gleichen Effekt.

unmontiert
quelle
1
Ja, ich habe __init__.pyin beiden Verzeichnissen. Ich denke, das Problem ist, dass das oberste Verzeichnis NICHT in PYTHONPATH ist, wenn PyLint ausgeführt wird, und ich bin nicht sicher, wie ich das beheben soll.
EMP
Der Symlink ist eine gute Idee, wird jedoch nur ab Windows Vista unterstützt und ich verwende XP. Ich nehme an, ich könnte versuchen, es hart zu verknüpfen ...
EMP
re hardlinking: Nein, mach es besser nicht. Ich habe damit gespielt und obwohl es sicherlich (in gewisser Weise) funktioniert, wird es nicht so funktionieren, wie Sie es erwarten.
Shylent
Symlinks sind keine gute Idee. Dies behebt nur das Problem auf Ihrem Computer. Wenn jemand anderes das Projekt auscheckt, wird es für ihn beschädigt.
Jonathan Hartley
12

Allgemeine Antwort auf diese Frage, die ich auf dieser Seite gefunden habe BITTE NICHT GEÖFFNET, WEBSITE IST BUGED

erstellen .pylintrcund hinzufügen

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

Ich weiß nicht, wie es mit WingIDE funktioniert, aber für die Verwendung von PyLint mit Geany habe ich meinen externen Befehl auf Folgendes gesetzt:

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

Dabei ist% f der Dateiname und% d der Pfad. Könnte für jemanden nützlich sein :)

Simon
quelle
4

Ich musste die Systemvariable aktualisieren PYTHONPATH, um meinen App Engine-Pfad hinzuzufügen. In meinem Fall musste ich nur meine ~/.bashrcDatei bearbeiten und die folgende Zeile hinzufügen:

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

Tatsächlich habe ich versucht, das init-hookerste festzulegen, aber dies hat das Problem in meiner Codebasis nicht konsistent behoben (nicht sicher warum). Nachdem ich es dem Systempfad hinzugefügt hatte (wahrscheinlich eine gute Idee im Allgemeinen), verschwanden meine Probleme.

Brian Moeskau
quelle
3

Eine Problemumgehung, die ich gerade erst entdeckt habe, besteht darin, PyLint nur für das gesamte Paket und nicht für eine einzelne Datei auszuführen. Irgendwie gelingt es dann, importierte Module zu finden.

EMP
quelle
Klingt gut; Wie?
Cees Timmerman
1
@CeesTimmerman pylint ... dirAus übergeordnetem Ordner ausführen . Dies muss __init__.pyin jedem Unterordner mit .pyDateien vorhanden sein.
yugr
3

Versuchen

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

Beachten Sie, dass in Python 3 die Syntax für den Teil in der elseKlausel lautet

from .. import one

Beim zweiten Gedanken wird dies wahrscheinlich Ihr spezifisches Problem nicht beheben. Ich habe die Frage falsch verstanden und dachte, dass two.py als Hauptmodul ausgeführt wird, aber das ist nicht der Fall. Und angesichts der Unterschiede in der Art und Weise, wie Python 2.6 (ohne Import absolute_importvon __future__) und Python 3.x Importe handhaben, müssten Sie dies für Python 2.6 sowieso nicht tun, glaube ich nicht.

Wenn Sie jedoch irgendwann zu Python 3 wechseln und ein Modul sowohl als Paketmodul als auch als eigenständiges Skript im Paket verwenden möchten, ist es möglicherweise eine gute Idee, so etwas wie beizubehalten

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

im Kopf.

EDIT: Und jetzt zu einer möglichen Lösung für Ihr eigentliches Problem. Führen Sie PyLint entweder in dem Verzeichnis aus, in dem sich Ihr oneModul befindet (möglicherweise über die Befehlszeile), oder geben Sie beim Ausführen von PyLint den folgenden Code ein:

import os

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

Als Alternative zum Spielen mit PYTHONPATH stellen Sie einfach sicher, dass das aktuelle Arbeitsverzeichnis das Verzeichnis ist, das es enthält one.py Sie beim Importieren enthalten.

(Wenn Sie sich Brians Antwort ansehen, könnten Sie wahrscheinlich den vorherigen Code zuweisen init_hook, aber wenn Sie das tun, können Sie einfach das Anhängen an sys.pathdas tun, was er tut, was etwas eleganter ist als meine Lösung.)

JAB
quelle
2

Der Schlüssel besteht darin, Ihr Projektverzeichnis hinzuzufügen, sys.pathohne die env-Variable zu berücksichtigen.

Für jemanden, der VSCode verwendet, ist hier eine einzeilige Lösung für Sie, wenn es ein Basisverzeichnis Ihres Projekts gibt:

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

Lassen Sie es mich ein wenig erklären:

  • re.search(r".+\/" + base_dir, os.getcwd()).group(): Basisverzeichnis entsprechend der Bearbeitungsdatei suchen

  • os.path.join(os.getcwd(), base_dir): Hinzufügen cwdzu sys.path, um die Befehlszeilenumgebung zu erfüllen


Zu Ihrer Information, hier ist meine .pylintrc:

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

chuyik
quelle
2

Ich hatte das gleiche Problem und habe es behoben, indem ich pylint in meiner virtuellen Umgebung installiert und dann eine .pylintrc-Datei zu meinem Projektverzeichnis hinzugefügt habe, die Folgendes in der Datei enthält:

[Master]
init-hook='sys.path = list(); sys.path.append("./Lib/site-packages/")'
Nate
quelle
Ich muss bestätigen, dass dadurch die E0611-Pylint-Fehler beseitigt werden, aber die E0401-Fehler bleiben bestehen.
np8
1

Vielleicht durch manuelles Anhängen des Verzeichnisses im PYTHONPATH?

sys.path.append(dirname)
Mario Mikić
quelle
Hmm, aber wo würdest du diesen Code platzieren? Ganz oben in jeder Datei? Ich nehme an, es würde funktionieren, aber es ist ein ziemlicher Hack, nur um PyLint zum Laufen zu bringen.
EMP
@Evgeny: Siehe die Antwort, die Brian M. Hunt kürzlich gepostet hat.
JAB
Und das Hinzufügen am Anfang jeder Datei funktioniert aus irgendeinem Grund nicht - PyLint scheint vollkommen zufrieden damit zu sein, Änderungen an sys.path zu ignorieren, die in den gescannten Modulen vorgenommen wurden. Ich habe mich nicht darum
gekümmert,
1

Ich hatte das gleiche Problem und da ich keine Antwort finden konnte, hoffe ich, dass dies jedem mit einem ähnlichen Problem helfen kann.

Ich benutze Flymake mit Epylint. Grundsätzlich habe ich einen Dired-Mode-Hook hinzugefügt, der prüft, ob das Dired-Verzeichnis ein Python-Paketverzeichnis ist. Wenn ja, füge ich es dem PYTHONPATH hinzu. In meinem Fall betrachte ich ein Verzeichnis als Python-Paket, wenn es eine Datei mit dem Namen "setup.py" enthält.

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

Hoffe das hilft.

user2826500
quelle
1

Falls jemand nach einer Möglichkeit sucht, Pylint als externes Tool in PyCharm auszuführen und es mit seinen virtuellen Umgebungen arbeiten zu lassen (warum ich auf diese Frage gekommen bin), habe ich es folgendermaßen gelöst:

  1. Fügen Sie unter PyCharm> Einstellungen> Extras> Externe Tools ein Element für Pylint hinzu oder bearbeiten Sie es.
  2. Stellen Sie in den Werkzeugeinstellungen des Dialogfelds Werkzeug bearbeiten die Option Programm für die Verwendung von Pylint aus dem Python-Interpreter-Verzeichnis ein: $PyInterpreterDirectory$/pylint
  3. Stellen Sie Ihre anderen Parameter im Feld Parameter ein, wie z. --rcfile=$ProjectFileDir$/pylintrc -r n $FileDir$
  4. Stellen Sie Ihr Arbeitsverzeichnis auf ein $FileDir$

Wenn Sie jetzt pylint als externes Tool verwenden, wird pylint in einem beliebigen Verzeichnis ausgeführt, das Sie mithilfe einer gemeinsamen Konfigurationsdatei ausgewählt haben, und es wird ein beliebiger Interpreter verwendet, der für Ihr Projekt konfiguriert ist (vermutlich Ihr virtueller Env-Interpreter).

tterry
quelle
1

Dies ist eine alte Frage, die jedoch nicht akzeptiert wurde. Daher schlage ich Folgendes vor: Ändern Sie die Importanweisung in two.py, um Folgendes zu lesen:

from .. import one

In meiner aktuellen Umgebung (Python 3.6, VSCode mit Pylint 2.3.1) wird die markierte Anweisung gelöscht.

Mike C.
quelle
1

Ich habe eine schöne Antwort gefunden . Bearbeiten Sie Ihren Pylintrc und fügen Sie im Master Folgendes hinzu

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
quelle
1

Wenn Sie Python installieren, können Sie den Pfad einrichten. Wenn der Pfad bereits definiert ist, können Sie ihn innerhalb von VS Code ausführen. Drücken Sie Strg + Umschalt + P und geben Sie Python ein: Wählen Sie Interpreter und wählen Sie die aktualisierte Version von Python aus. Folgen Sie diesem Link für weitere Informationen unter https://code.visualstudio.com/docs/python/environments

Nadeem
quelle
0

Wenn Sie vscode verwenden, stellen Sie sicher, dass sich Ihr Paketverzeichnis außerhalb des Verzeichnisses _pychache__ befindet.

Vikas Bhutani
quelle
0

Wenn Sie Cython unter Linux verwenden, habe ich das Entfernen von module.cpython-XXm-X-linux-gnu.soDateien in meinem Projektzielverzeichnis behoben .

M. Andrade
quelle
0

Fügen Sie diesen Code einfach in die Datei .vscode / settings.json ein

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

Dadurch wird der Speicherort von pylint benachrichtigt (dies ist eine Fehlerprüfung für Python).

user3395246
quelle
-1

Hallo, ich konnte die Pakete aus einem anderen Verzeichnis importieren. Ich habe gerade Folgendes getan: Hinweis: Ich verwende VScode

Schritte zum Erstellen eines Python-Pakets Die Arbeit mit Python-Paketen ist sehr einfach. Alles was Sie tun müssen ist:

Erstellen Sie ein Verzeichnis und geben Sie den Namen Ihres Pakets an. Setzen Sie Ihre Klassen ein. Erstellen Sie eine Init .py-Datei im Verzeichnis

Beispiel: Sie haben einen Ordner namens Framework, in dem Sie alle benutzerdefinierten Klassen behalten, und Ihre Aufgabe besteht darin, nur eine Init zu erstellen .py-Datei im Ordner Framework .

Und während des Imports müssen Sie auf diese Weise importieren --->

von der Framework-Importbasis

Der E0401-Fehler verschwindet also. Framework ist der Ordner, in dem Sie gerade init .py erstellt haben, und base ist Ihr benutzerdefiniertes Modul, in das Sie importieren und daran arbeiten müssen. Hoffe, es hilft !!!!

SUNEEL KAUSHIK S.
quelle