ImportError: Kein Modul mit dem Namen - Python


68

Ich habe eine Python-Anwendung mit der folgenden Verzeichnisstruktur:

src
 |
 +---- main
 |
 +---- util
 |
 +---- gen_py
         |
         +---- lib

Im Paket main habe ich ein Python-Modul namens MyServer.py, das eine import-Anweisung wie folgt enthält :

from gen_py.lib import MyService

Damit diese Anweisung funktioniert, habe ich die folgende Zeile am Anfang von MyServer.py platziert :

import sys
sys.path.append('../gen_py/lib')

Wenn ich MyServer.py im Terminal ausführe, wird folgende Fehlermeldung angezeigt:

ImportError: Kein Modul mit dem Namen gen_py.lib

Was fehlt mir hier?


Mit welcher Befehlszeile haben Sie MyServer.py ausgeführt? In welchem ​​Verzeichnis waren Sie?
Mark Hildreth

Antworten:


80

Bei Ihrer Änderung von wird sys.pathdavon ausgegangen, dass sich das aktuelle Arbeitsverzeichnis immer in befindet main/. Das ist nicht der Fall. Fügen Sie stattdessen einfach das übergeordnete Verzeichnis hinzu zu sys.path:

import sys
import os.path

sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import gen_py.lib

Vergessen Sie nicht, eine Datei __init__.pyin gen_py und lib aufzunehmen - andernfalls werden sie nicht als Python-Module erkannt.


Ich habe das gleiche Problem. Ich benutze Windows, Eclipse. Was sollen wir in Eclipse tun?
Ayse

@Ceren Dieser Code sollte in jeder IDE funktionieren. Ihre IDE (oder genauer gesagt das Python-Plugin dafür) führt den Python-Code möglicherweise nicht aus. In diesem Fall müssen Sie den Suchpfad wahrscheinlich irgendwo konfigurieren. Fühlen Sie sich frei , eine neue Frage dazu zu stellen.
Phihag

@phihag Danke! Ich hatte vor ungefähr einer Stunde eine Frage gestellt, zögern
Ayse

Ist es möglich, dies irgendwo nicht in meiner Hauptanwendung zu platzieren? Ich habe diese Lösung verwendet, um meinen ähnlichen Fehler zu beheben, aber jetzt habe ich eine Datei, die mit Importen überall unordentlich aussieht. Ich dachte, es gibt eine Möglichkeit, dies in der Init- Datei zu tun, aber ich kann keine guten Beispiele finden.
Mark II

Was löst sich sys.path.append(os.path.join(os.path.dirname(__file__), '..')) auf? Warum ist es nicht sys.path.append(os.path.join('..', os.path.dirname(__file__)))?
Alex

6

Damit der Import des Python-Moduls funktioniert, muss "src" in Ihrem Pfad sein, nicht "gen_py / lib".

Bei der Verarbeitung eines Imports wie import gen_py.libsucht es nach einem Modul gen_pyund dann nach einem Submodul lib.

Da sich das Modul gen_pynicht in "../gen_py/lib" befindet (es befindet sich in ".."), trägt der von Ihnen hinzugefügte Pfad nicht zum Importvorgang bei.

Versuchen Sie, je nachdem, von wo aus Sie es ausführen, den relativen Pfad zum Ordner "src" hinzuzufügen. Vielleicht ist es das sys.path.append('..'). Möglicherweise haben Sie auch Erfolg, wenn Sie das Skript direkt im Ordner src über relative Pfade wie ausführenpython main/MyServer.py


Das ist nicht was ich sagte. Sie hängen gen_py / lib nicht an den Pfad an, wenn Sie "gen_py.lib" importieren. Sie fügen den Ordner gen_py hinzu, der sich in diesem Fall wahrscheinlich ".." befindet.
Lunixbochs

5
from ..gen_py.lib import MyService

oder

from main.gen_py.lib import MyService

Stellen Sie sicher, dass Sie __init__.pyin jedem Verzeichnis eine (mindestens leere) Datei haben.


3

__init__.pyStellen Sie sicher , dass Python enthalten ist , damit Python weiß, dass diese Verzeichnisse Pakete enthalten


3

Dies ist der Fall, wenn Sie ein Paket erstellen und beim Import einen Fehler feststellen. Ich habe es auf die harte Tour gelernt. Die Antwort ist nicht, das Paket zum Python-Pfad hinzuzufügen oder es programmgesteuert zu machen (was ist, wenn Ihr Modul installiert wird und Ihr Befehl es erneut hinzufügt?), Das ist ein schlechter Weg.

Das Richtige ist: 1) Verwenden Sie virtualenv pyvenv-3.4 oder ähnliches. 2) Aktivieren Sie den Entwicklungsmodus - $ python setup.py Develop


0

Stellen Sie sicher, dass das Stammprojektverzeichnis in der Ausgabe von sys.path angezeigt wird. Wenn nicht, fügen Sie bitte den Pfad des Stammprojektverzeichnisses zu sys.path hinzu.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.