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?
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.
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
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.
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.
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 :)
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"
}
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.
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/")'
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.
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.)
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
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.
Vielleicht durch manuelles Anhängen des Verzeichnisses im PYTHONPATH?
sys.path.append(dirname)
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:
$PyInterpreterDirectory$/pylint
--rcfile=$ProjectFileDir$/pylintrc -r n $FileDir$
$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).
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.
wenn Sie vscode verwenden, stellen Sie sicher, dass sich das Paketverzeichnis nicht im Verzeichnis _pychache__ befindet.