2015-11-23 8 views
16

Ich habe ein Python-Projekt finden (was ich in einem virtualenv laufen), und das hat die folgende Struktur:Python kann nicht mein Modul

Project 
├───.git 
├───venv 
└───src 
    ├───__init__.py 
    ├───mymodules 
    │ ├───__init__.py 
    │ ├───module1.py 
    │ └───module2.py 
    └───scripts 
     ├───__init__.py 
     └───script.py 

script.py

import src.mymodules.module1 
... 

Ich starte das Projekt mit venv aktiviert und aus dem Projekt-Verzeichnis mit dem folgenden Befehl:

(venv)$ python src/scripts/script.py 

Das Skript läuft aber gibt aus den folgenden Fehler vor dem Verlassen:

Traceback (most recent call last): 
    File "src/scripts/script.py", line 1, in <module> 
    import src.mymodules.module1 
ImportError: No module named src.mymodules.module1 

ich versucht habe, die Python-Shell läuft und versucht, das Modul von dort zu importieren und es gab keine Fehler. Ich habe _ _init__.py in jedem Verzeichnis innerhalb von src. Ist Python der Ansicht, dass das Arbeitsverzeichnis src/scripts ist? Warum passiert das und wie kann ich src zum Arbeitsverzeichnis machen, wenn das der Fall ist?

+0

Python 2 oder 3? 3 hat eine andere Möglichkeit, Paketmodulimporte zu verarbeiten. – Mego

+0

@Mego Python 2.7 – CrazyJony

+0

Dies könnte helfen http://stackoverflow.com/questions/33773202/how-to-import-a-class-from-a-different-folder-in-python/33773635#33773635 –

Antwort

10

Im Wesentlichen, wenn Sie script.py direkt ausführen, weiß es nicht, dass es Teil eines Submoduls von src ist, noch weiß es, wo ein Modul mit dem Namen src sein könnte. Dies ist der Fall entweder in Python 2 oder 3.

Wie Sie wissen, findet Python Module basierend auf dem Inhalt von . Um ein Modul zu importieren, muss es sich entweder in einem Verzeichnis befinden, das in sys.path aufgeführt ist, oder in demselben Verzeichnis wie das von Ihnen ausgeführte Skript.

Wenn Sie sagen python src/scripts/script.py, sys.path die Project/src/scripts/ enthält (weil dort script.py befindet), aber nicht Project. Da sich Project nicht im Pfad befindet, können die Module in diesem Verzeichnis (src) nicht importiert werden.

dies zu beheben:

Ich gehe davon aus, dass Ihre script.py ein Einstiegspunkt für Ihren src Modul ist (zum Beispiel, vielleicht ist es das Hauptprogramm). Wenn das wahr ist, dann könnte man es beheben, indem script.py bis zu dem gleichen Niveau wie src bewegen:

Project 
├───.git 
├───venv 
|───script.py  <--- script.py moves up here 
└───src 
    ├───__init__.py 
    └───mymodules 
     ├───__init__.py 
     ├───module1.py 
     └───module2.py 

Auf diese Weise script.py frei alles in src importieren kann, aber nichts in srcscript.py importieren.

Wenn das nicht der Fall ist, und script.py ist wirklich ein Teil von src, Sie -m Argument der Python script.py als Teil des src Modul wie so auszuführen, verwenden können:

$ python -m src.scripts.script 

Weil Sie gesagt haben Python welches Modul du führst (src), es wird im Pfad sein. So, script.py wird bewusst sein, dass es ein Submodul von src ist, und dann in der Lage sein wird, von src zu importieren.

Seien Sie in dieser Situation jedoch vorsichtig - es besteht die Möglichkeit, einen kreisförmigen Import zu erstellen, wenn etwas in srcsrc.scripts.script importiert.

import sys 
sys.path.insert(0, '/path/to/Project') # location of src 

Das funktioniert zwar, es ist nicht in der Regel bevorzugt meine:


Als Alternative zu diesen beiden Ansätzen, können Sie die sys.path direkt in script.py ändern. Es erfordert script.py, um genau zu wissen, wie Ihr Code ausgelegt ist, und kann Import-Verwirrung verursachen, wenn ein anderes Python-Programm jemals versucht, script.py zu importieren.

+0

Danke, alle 3 Optionen funktionieren. Der erste ist keine Option für dieses Projekt. Der dritte ist nicht sehr elegant aus dem Grund, den Sie angegeben haben. Momentan denke ich, dass ich 'python -m src.scripts.script' verwenden werde. Ich dachte, es wäre genug, um es wie ein Paket zu strukturieren, wie ich in anderen Fragen hier festgestellt habe? – CrazyJony

+0

Python geht nicht auf Verzeichnissebenen, um Pakete aus verschiedenen Gründen zu finden. Und Untermodule können und importieren Geschwister, aber meistens sind Pakete dafür gedacht, von anderen Programmen verwendet zu werden (und in einem Systempaketverzeichnis installiert zu werden), nicht notwendigerweise, um Programme in sich selbst zu sein. Dieser Teil von Python kann verwirrend sein, aber es macht Sinn. – Seth

0
Project 
├───.git 
├───venv 
└───src 
    ├───__init__.py 
    ├───mymodules 
    │ ├───__init__.py 
    │ ├───module1.py 
    │ └───module2.py 
    └───scripts 
     ├───__init__.py 
     └───script.py 

Alternativ können Sie wie die

import os 
import sys 
sys.path.append(os.path.join(os.path.dirname(__file__),'../../')) 
import src.mymodules.module1 

Nun folgt in Ihrem script.py importieren Sie script.py Datei von jedem Ort ausgeführt werden können.

e.g : 
python script.py 
python /path to folder/script.py