2015-11-23 2 views
16

私のモジュールを見つけることができません、それは以下の構造を有する:Pythonは私が(私はvirtualenvの内で実行)Pythonのプロジェクトを持っている

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

script.pyを

import src.mymodules.module1 
... 

私はvenvを有効にしてプロジェクトを実行し、次のコマンドを使ってProjectディレクトリから実行します:

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

スクリプトが実行されますが終了する前に、次のエラーを与える:

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 

私はPythonシェルを実行しているし、そこからモジュールをインポートしようと試みたが、それは何のエラーを与えませんでした。 src内のすべてのディレクトリに_ _init__.pyがあります。 Pythonは作業ディレクトリをsrc/scriptsとみなしていますか?なぜそれが起こっているのですか?その場合、srcを作業ディレクトリにする方法はありますか?

+0

Python 2または3? 3では、パッケージモジュールのインポートを扱う方法が異なります。 – Mego

+0

@Mego Python 2.7 – CrazyJony

+0

これは役立つかもしれないhttp://stackoverflow.com/questions/33773202/how-to-import-a-class-from-a-different-folder-in-python/33773635#33773635 –

答えて

10

script.pyを直接実行すると、サブモジュールの一部がsrcであることや、srcというモジュールがどこにあるのかわからないことがあります。ご存知のように、これはどちらかのpython 2または3

場合であり、Pythonはsys.pathの内容に基づいてモジュールを検索します。モジュールをインポートするには、sys.pathに記載されているディレクトリ、または実行しているスクリプトと同じディレクトリにモジュールを置く必要があります。あなたがpython src/scripts/script.pyを言うとき

sys.pathProject/src/scripts/script.pyが配置されている場所それはだから)ではなく、Projectが含まれています。 Projectがパスにないため、そのディレクトリ内のモジュール(src)をインポートすることはできません。

はこれを修正するために:私はあなたの script.pyがあなたの srcモジュールのエントリポイントであると仮定してい

(例えば、多分それは、メインプログラムです)。それが本当ならば、あなたはsrcと同じレベルにまでscript.py移動して、それを修正することができます:

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

この方法は、script.pyは自由にsrcに何かをインポートすることができますが、srcには何もscript.pyをインポートすることはできません。

$ python -m src.scripts.script 

あなたが言ったのでパイソン:

付属していない場合、およびscript.pyは本当にあなたがsrcモジュールので、同様の一環としてscript.pyを実行するためにPythonの-m引数を使用することができ、srcの一部であり、実行中のモジュール(src)、それはパスになります。だから、script.pyは、それがsrcのサブモジュールだと承知しているであろうし、その後srcからインポートすることができるようになります。

srcに何かがsrc.scripts.scriptをインポートすると、循環インポートを作成する可能性があります。これらのアプローチの両方に代わるものとして


、あなたはscript.pyで直接sys.pathを変更することができます。

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

を、これは動作しますが、それは通常私の好みではありません。コードがどのようにレイアウトされているかを正確に知るにはscript.pyが必要で、別のPythonプログラムがscript.pyをインポートしようとするとインポートの混乱を招く可能性があります。

+0

ありがとう、すべての3つのオプションが動作します。最初のプロジェクトはこのプロジェクトのオプションではありません。第3のものはあなたが述べた理由であまり優雅ではありません。今のところ、 'python -m src.scripts.script'を使っています。私はそれがパッケージのように構造化するのに十分であると思った、私がここに他の質問で述べたように? – CrazyJony

+0

Pythonはさまざまな理由でパッケージを見つけるために "up"ディレクトリレベルにはなりません。サブモジュールは兄弟をインポートしたりインポートしたりすることができますが、主にパッケージは他のプログラムで使用されることが意図されています(システムパッケージディレクトリにインストールされる)。 Pythonのこの部分は混乱する可能性がありますが、意味があります。 – Seth

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

代わりに、あなたは今、あなたは任意の場所からscript.pyファイルを実行することができ、あなたのscript.py

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

で次のようにインポートすることができます。

e.g : 
python script.py 
python /path to folder/script.py 
関連する問題