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を作業ディレクトリにするにはどうすればよいですか?
基本的に、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.py
がsrc
モジュールのエントリポイントであると仮定しています(たとえば、メインプログラムかもしれません)。それが本当なら、script.py
をsrc
と同じレベルに移動することで修正できます:
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
をインポートできません。
そうではなく、script.py
が実際にsrc
の一部である場合、pythonの -m
引数を使用してscript.py
を一部として実行できます。 src
モジュールのように:
$ python -m src.scripts.script
python実行中のモジュール(src
)を指定したので、それはパスにあります。したがって、script.py
はそれがsrc
のサブモジュール。その後、src
からインポートできます。
ただし、この状況には注意してください-src
の何かがsrc.scripts.script
をインポートする場合、循環インポートを作成する可能性があります。
これらのアプローチの両方の代替として、sys.path
をscript.py
で直接変更できます。
import sys
sys.path.insert(0, '/path/to/Project') # location of src
これは機能しますが、通常は私の好みではありません。コードがどのようにレイアウトされているかを正確に知るにはscript.py
が必要です。また、別のpythonプログラムがscript.py
。
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
Pytest
またはcoverage
を扱うときにこの問題に直面した場合。 __init__.py
ファイルを追加すると、ほとんどの場合が解決します。
別の解決策は、ファイル名「xxx(任意の名前).pth」を作成し、プロジェクトディレクトリ(srcのマザーディレクトリ)を書き込むことです。このファイルを「/ virtual_env/lib/pythonXX/site-packages /」に配置します。このように、スクリプトにsys.pathをインポートする必要はありません。