wake-up-neo.com

PyLint Fehler beim Importieren nicht möglich - wie wird PYTHONPATH gesetzt?

Ich lasse PyLint unter Windows in Wing IDE laufen. 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

In two.py habe ich import one und dies funktioniert zur Laufzeit gut, da das Verzeichnis der obersten Ebene (von dem myapp.py ausgeführt wird) im Python-Pfad liegt. Wenn ich PyLint auf two.py starte, bekomme ich einen Fehler:

F0401: Unable to import 'one'

Wie kann ich das beheben?

112
EMP

Ich kenne zwei Möglichkeiten.

Ändern Sie die Umgebungsvariable PYTHONPATH so, dass das Verzeichnis oberhalb Ihres Moduls enthalten ist.

Alternativ können Sie ~/.pylintrc bearbeiten, um das Verzeichnis über Ihrem Modul einzuschließen.

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

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

Beide Optionen sollten funktionieren.

Hoffentlich hilft das.

100
Brian M. Hunt

1) sys.path ist eine Liste. 

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

3) Wie gesagt, verwenden Sie init-hook (achten Sie auf 'und' die Pylint-Analyse 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
20
macm

Die Lösung zum Ändern des Pfads in init-hook ist gut, aber ich kann die Tatsache, dass ich den absoluten Pfad dort hinzufügen musste, nicht mögen. Als Ergebnis kann ich diese Pylintrc-Datei nicht mit den Entwicklern des Projekts teilen. Diese Lösung, die den relativen Pfad zur Pylintrc-Datei verwendet, 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 auch pylint.config.PYLINTRC existiert und denselben Wert wie find_pylintrc() hat.

19
alex_koval

Verfügen Sie in beiden Verzeichnissen über eine leere __init__.py-Datei, die Python darüber informiert, dass die Verzeichnisse Module sind?

Die grundlegende Gliederung, wenn Sie nicht innerhalb des Ordners ausgeführt werden (z. B. von pylint's, obwohl ich das noch nicht verwendet habe):

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

So kennt der Python-Interpreter das Modul ohne Verweis auf das aktuelle Verzeichnis. Wenn also pylint von seinem eigenen absoluten Pfad aus ausgeführt wird, kann es auf functions_etc.py als topdir.functions_etc oder topdir.subdir.other_functions zugreifen, sofern sich topdir in der PYTHONPATH befindet.

UPDATE: Wenn das Problem nicht die __init__.py-Datei ist, versuchen Sie einfach, Ihr Modul zu c:\Python26\Lib\site-packages zu kopieren oder zu verschieben - dies ist ein üblicher Ort, um zusätzliche Pakete zu platzieren, und wird sich definitiv auf Ihrem Pythonpfad befinden. Wenn Sie wissen, wie Sie Windows-symbolische Links oder gleichwertige Verknüpfungen herstellen (ich nicht!), Können Sie dies auch tun. Es gibt viele weitere Optionen hier: http://docs.python.org/install/index.html , einschließlich der Option, sys.path mit dem Benutzerverzeichnis Ihres Entwicklungscodes anzuhängen, in der Praxis jedoch Normalerweise verknüpfen Sie mein lokales Entwicklungsverzeichnis nur symbolisch mit Site-Paketen - das Kopieren von Dateien hat den gleichen Effekt.

15
unmounted

Ich weiß nicht, wie es mit WingIDE funktioniert, aber um PyLint mit Geany zu verwenden, setze ich meinen externen Befehl auf:

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

dabei steht% f für den Dateinamen und% d für den Pfad. Könnte für jemanden nützlich sein :)

5
simon

Das Problem kann durch Konfigurieren des Pylint-Pfads unter venv gelöst werden: $ Cat .vscode/settings.json 

{
    "python.pythonPath": "venv/bin/python",
    "python.linting.pylintPath": "venv/bin/pylint"
}
4
jeanerpp

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

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

In der Tat habe ich zuerst versucht, den init-hook einzustellen, aber dies löste das Problem in meiner Codebasis nicht konsistent (nicht sicher warum). Nachdem ich es zum Systempfad hinzugefügt hatte (wahrscheinlich eine gute Idee im Allgemeinen), gingen meine Probleme weg.

4
Brian Moeskau

Ich hatte das gleiche Problem und behebte dieses Problem, indem ich pylint in meinem virtualenv installierte und dann eine .pylintrc-Datei zu meinem Projektverzeichnis mit folgendem in der Datei hinzufügt:

[Master]
init-hook='sys.path = list(); sys.path.append("./Lib/site-packages/")'
2
Nate

Eine Problemlösung, die ich gerade erst entdeckt habe, ist, PyLint für das gesamte Paket und nicht nur für eine einzige Datei auszuführen. Irgendwie findet es dann das importierte Modul.

2
EMP

Versuchen

if __== '__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 else -Klausel lautet

from .. import one

Auf den zweiten Blick 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. Unter Berücksichtigung der Unterschiede in der Art und Weise, wie Python 2.6 (ohne absolute_import aus __future__ zu importieren) und Python 3.x mit Importen umzugehen, ist dies nicht erforderlich Mach das für Python 2.6, 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 beizubehalten

if __== '__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 nun zu einer möglichen Lösung für Ihr eigentliches Problem. Führen Sie PyLint entweder in dem Verzeichnis aus, das Ihr one -Modul enthält (möglicherweise über die Befehlszeile), oder geben Sie den folgenden Code ein, wenn Sie PyLint ausführen:

import os

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

Stellen Sie als Alternative zum Spielen mit PYTHONPATH sicher, dass das aktuelle Arbeitsverzeichnis das Verzeichnis ist, das one.py enthält, wenn Sie den Import durchführen.

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

2
JAB

Der Schlüssel ist das Hinzufügen Ihres Projektverzeichnisses zu sys.path, ohne die Umgebungsvariable zu berücksichtigen.

Für jemanden, der VSCode verwendet, gibt es 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 mich es etwas erklären:

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

  • os.path.join(os.getcwd(), base_dir): Fügen Sie cwd zu sys.path hinzu, um die Befehlszeilenumgebung zu erfüllen


Zu Ihrer Information, hier ist meine .pylintrc:

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

2
chuyik

Ich hatte das gleiche Problem und da ich keine Antwort finden konnte, hoffe ich, dass dies jedem helfen kann, der ein ähnliches Problem hat. 

Ich benutze Flymake mit Epylint. Grundsätzlich habe ich einen Dired-Mode-Hook hinzugefügt, der überprüft, ob das Dired-Verzeichnis ein Python-Paketverzeichnis ist. Wenn es so ist, füge ich es dem PYTHONPATH hinzu. In meinem Fall betrachte ich ein Verzeichnis als Python-Paket, wenn es eine Datei namens "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.

1
user2826500

Vielleicht durch manuelles Anhängen des Verzeichnisses im PYTHONPATH?

sys.path.append(dirname)
1
Mario Mikić

Falls jemand nach einer Möglichkeit sucht, Pylint als externes Werkzeug in PyCharm zu verwenden und es mit seiner virtuellen Umgebung arbeiten zu lassen (warum ich zu dieser Frage gekommen bin), habe ich es hier gelöst:

  1. Fügen Sie in PyCharm> Voreinstellungen> Extras> Externe Werkzeuge ein Element für pylint hinzu oder bearbeiten Sie es.
  2. Legen Sie in den Tool-Einstellungen des Dialogfelds Edit Tool fest, dass Pylint aus dem Python-Interpreter-Verzeichnis verwendet wird: $PyInterpreterDirectory$/pylint
  3. Stellen Sie Ihre anderen Parameter in das Feld Parameter ein, wie zum Beispiel: --rcfile=$ProjectFileDir$/pylintrc -r n $FileDir$
  4. Stellen Sie Ihr Arbeitsverzeichnis auf $FileDir$

Wenn Sie nun pylint als externes Tool verwenden, wird pylint in einem beliebigen Verzeichnis ausgeführt, das Sie mit einer gemeinsamen Konfigurationsdatei ausgewählt haben, und den für Ihr Projekt konfigurierten Interpreter verwenden (der vermutlich Ihr Virtualenv-Interpreter ist).

1
tterry

Dies ist eine alte Frage, die aber noch nicht beantwortet wurde. Daher schlage ich Folgendes vor: Ändern Sie die import-Anweisung in two.py in:

from .. import one

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

0
Mike C

wenn Sie vscode verwenden, stellen Sie sicher, dass sich das Paketverzeichnis nicht im Verzeichnis _pychache__ befindet.

0
Vikas Bhutani