Wie behebe ich den Fehler "ImportError: Kein Modul mit dem Namen ..." in Python?

114

Wie kann dieser ImportError-Fehler richtig behoben werden?

Ich habe folgende Verzeichnisstruktur:

/home/bodacydo
/home/bodacydo/work
/home/bodacydo/work/project
/home/bodacydo/work/project/programs
/home/bodacydo/work/project/foo

Und ich bin im Verzeichnis

/home/bodacydo/work/project

Nun, wenn ich tippe

python ./programs/my_python_program.py

Ich bekomme sofort

ImportError: No module named foo.tasks

Das ./programs/my_python_program.pyenthält die folgende Zeile:

from foo.tasks import my_function

Ich kann nicht verstehen, warum Python nicht findet ./foo/tasks.py- es ist da.

Wenn ich es von der Python-Shell aus mache, dann funktioniert es:

python
>>> from foo.tasks import my_function

Es funktioniert nur nicht, wenn ich es per python ./programs/my_python_program.pySkript aufrufe.

bodacydo
quelle

Antworten:

118

Python fügt nicht das aktuelle Verzeichnis hinzu sys.path, sondern das Verzeichnis, in dem sich das Skript befindet. Fügen Sie /home/bodacydo/work/projectentweder sys.pathoder hinzu $PYTHONPATH.

Ignacio Vazquez-Abrams
quelle
8
Was bringt es dann, init .py im Stammordner zu haben? Es scheint keinen Zweck zu haben, wenn Sie entweder sys.path oder den Pythonpath bearbeiten.
11
@Editor: Gibt __init__.pynur an, dass das Verzeichnis als Paket behandelt werden soll, wenn sich das übergeordnete Verzeichnis entweder in sys.patheinem Paket befindet oder selbst ein Paket ist.
Ignacio Vazquez-Abrams
3
Überprüfen Sie außerdem die Berechtigungen für den Ordner. Das war das Problem in meinem Fall.
SidJ
15
Verwenden Sieexport PYTHONPATH=`pwd`
rodorgas
1
Was für mich funktioniert hat, war, $ PYTHONPATH das übergeordnete Verzeichnis des Projekts hinzuzufügen. In Ihrem Fall ist dies: /home/bodacydo/work... siehe diese Antwort
maledr53
33

Haben Sie eine Datei __init__.pyim Verzeichnis foo? Wenn nicht, erkennt Python foo nicht als Python-Paket.

Weitere Informationen finden Sie im Abschnitt zu Paketen im Python-Tutorial.

Dave Kirby
quelle
Danke und ja, ich hatte __init__.py. Das Problem war diesmal mit $PYTHONPATH. Ignacios Lösung hat funktioniert.
Bodacydo
1
Die init .py-Dateien sind erforderlich, damit Python die Verzeichnisse als Pakete enthaltend behandelt. Auf diese Weise wird verhindert, dass Verzeichnisse mit einem allgemeinen Namen, z. B. eine Zeichenfolge, unbeabsichtigt gültige Module verbergen, die später im Modul-Suchpfad auftreten. Im einfachsten Fall kann init .py nur eine leere Datei sein
Panofish
Danke, dass du mich irgendwann gerettet hast.
cpu_meltdown
9

Hier ist eine schrittweise Lösung:

  1. Fügen Sie ein Skript mit dem Namen run.pyin /home/bodacydo/work/projectund bearbeiten es wie folgt aus :

    import programs.my_python_program
    programs.my_python_program.main()

    (Ersetzen Sie main()durch Ihre entsprechende Methode in my_python_program.)

  2. Gehe zu /home/bodacydo/work/project
  3. Lauf run.py

Erläuterung: Da Python an PYTHONPATH den Pfad des Skripts anhängt, von dem es ausgeführt run.pywird , wird das Ausführen angehängt /home/bodacydo/work/project. Und voilà , import foo.taskswird gefunden.

Cyborg
quelle
8

Beispiellösung zum Hinzufügen der Bibliothek zu Ihrem PYTHONPATH.

  1. Fügen Sie die folgende Zeile in Ihr ~ / .bashrc ein oder führen Sie sie einfach direkt aus:

    export PYTHONPATH="$PYTHONPATH:$HOME/.python"
  2. Verknüpfen Sie dann Ihre gewünschte Bibliothek mit Ihrem ~ / .python-Ordner, z

    ln -s /home/user/work/project/foo ~/.python/
Kenorb
quelle
6

Eine bessere Lösung als die Einstellung PYTHONPATHist die Verwendungpython -m module.path

Dies wird korrekt eingestellt sys.path[0]und ist eine zuverlässigere Möglichkeit, Module auszuführen.

Ich habe eine schnelle writeup über dieses Problem, da andere Beantworter den erwähnten Grund dafür ist , python path/to/file.pysetzt path/toam Anfang der PYTHONPATH( sys.path).

Anthony Sottile
quelle
2

In meinen Gedanken muss ich berücksichtigen, dass der fooOrdner eine eigenständige Bibliothek ist. Ich könnte in Betracht ziehen, es in den Lib\site-packagesOrdner innerhalb einer Python-Installation zu verschieben. Vielleicht möchte ich dort eine foo.pthDatei hinzufügen .

Ich weiß, dass es eine Bibliothek ist, da ./programs/my_python_program.pydie folgende Zeile enthält:

from foo.tasks import my_function

Es spielt also keine Rolle, dass ./programses sich um einen Geschwisterordner handelt ./foo. Es ist die Tatsache, dass my_python_program.pyes als Skript wie folgt ausgeführt wird:

python ./programs/my_python_program.py

Quamrana
quelle
0

Wenn Sie dieses Problem haben, wenn Sie eine installierte Version verwenden setup.py, stellen Sie bei der Verwendung sicher, dass Ihr Modul darin enthalten istpackages

setup(name='Your program',
    version='0.7.0',
    description='Your desccription',
    packages=['foo', 'foo.bar'], # add `foo.bar` here
Danon
quelle