web-dev-qa-db-ja.com

Pythonモジュールが見つかりません

pythonプロジェクト(virtualenv内で実行))があり、次の構造を持っています。

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 Shellを実行し、そこからモジュールをインポートしようとしてもエラーは発生しませんでした。src内のすべてのディレクトリに_ _init__.pyがあります。Is python作業ディレクトリをsrc/scriptsとみなすのはなぜですか?どうしてですか?その場合、srcを作業ディレクトリにするにはどうすればよいですか?

27
CrazyJony

基本的に、script.pyを直接実行すると、それがsrcのサブモジュールの一部であることも、srcという名前のモジュールがどこにあるかもわかりません。これは、python 2または3。

ご存じのとおり、Pythonは sys.path の内容に基づいてモジュールを検索します。モジュールをインポートするには、次のディレクトリに配置する必要があります。 sys.pathにリストされているか、実行中のスクリプトと同じディレクトリにあります。

python src/scripts/script.pyと言うと、sys.pathにはProject/src/scripts/が含まれますが(script.pyが存在するため)、Projectは含まれません。 Projectはパスにないため、そのディレクトリ内のモジュール(src)はインポートできません。

これを修正するには:

私はあなたのscript.pysrcモジュールのエントリポイントであると仮定しています(たとえば、メインプログラムかもしれません)。それが本当なら、script.pysrcと同じレベルに移動することで修正できます:

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

このように、script.pysrcに何でも自由にインポートできますが、srcにはscript.pyをインポートできません。

そうではなく、script.pyが実際にsrcの一部である場合、pythonの -m 引数を使用してscript.pyを一部として実行できます。 srcモジュールのように:

$ python -m src.scripts.script

python実行中のモジュール(src)を指定したので、それはパスにあります。したがって、script.pyはそれがsrcのサブモジュール。その後、srcからインポートできます。

ただし、この状況には注意してください-srcの何かがsrc.scripts.scriptをインポートする場合、循環インポートを作成する可能性があります。


これらのアプローチの両方の代替として、sys.pathscript.pyで直接変更できます。

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

これは機能しますが、通常は私の好みではありません。コードがどのようにレイアウトされているかを正確に知るにはscript.pyが必要です。また、別のpythonプログラムがscript.py

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

または、script.pyで次のようにインポートできます。

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

これで、任意の場所からscript.pyファイルを実行できます。

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

Pytestまたはcoverageを扱うときにこの問題に直面した場合。 __init__.pyファイルを追加すると、ほとんどの場合が解決します。

0
azzamsa

別の解決策は、ファイル名「xxx(任意の名前).pth」を作成し、プロジェクトディレクトリ(srcのマザーディレクトリ)を書き込むことです。このファイルを「/ virtual_env/lib/pythonXX/site-packages /」に配置します。このように、スクリプトにsys.pathをインポートする必要はありません。

0
Guiliang Liu