Python 3.7.1をmacOS Mojaveバージョン10.14.1で使用しています。
これは私のディレクトリ構造です:
man/
Mans/
man1.py
MansTest/
SoftLib/
Soft/
SoftWork/
manModules.py
Unittests/
man1test.py
man1.py
には、次のimportステートメントが含まれています変更したくない:
from Soft.SoftWork.manModules import *
man1test.py
には、次のimportステートメントが含まれています。
from ...MansTest.SoftLib import Soft
from ...Mans import man1
man1test.py
はman1test.py
の関数にアクセスする必要があるため、man1.py
の2番目のimportが必要です。
最初のインポート(Soft)の背後にある私の理論的根拠は、前述のman1.py
のimportステートメントを容易にすることでした。
しかし、私の期待に反して、man1.py
のimportステートメントは次のようになります。
ModuleNotFoundError: No module named 'Soft'
私が走るとき
python3 -m man.MansTest.Unittests.man1test
man /の上のディレクトリから。
man1.py
andのimportステートメントを変更せずにこのエラーを解決する方法はありますかに何も追加しませんsys.path?
編集:元の質問のバージョンからpython3 -m man.ManTest.Unittests.man1test
がpython3 -m man.MansTest.Unittests.man1test
に変更されました
セットアップにはいくつかの混乱する要件がありますが、私はあなたが望むものをあなたに与えるように努めます。
[〜#〜]最初[〜#〜]、man1.pyfromman1test.pyANDmanModules.pyfromman1.py、ファイルを パッケージとモジュール として適切に設定する必要があります。
パッケージは、「ドット付きモジュール名」を使用してPythonのモジュール名前空間を構造化する方法です。たとえば、モジュール名
A.B
は、B
というパッケージ内のA
というサブモジュールを示します。...
パッケージをインポートするとき、Pythonは
sys.path
上のディレクトリを検索して、パッケージのサブディレクトリを探します。
__init__.py
ファイルは、Pythonをディレクトリをパッケージを含むものとして扱うために必要です。これは、string
などの一般的な名前のディレクトリが意図せずに行われないようにするために行われますモジュール検索パスで後で発生する有効なモジュールを非表示にします。
次のように設定する必要があります。
man
|- __init__.py
|- Mans
|- __init__.py
|- man1.py
|- MansTest
|- __init.__.py
|- SoftLib
|- Soft
|- __init__.py
|- SoftWork
|- __init__.py
|- manModules.py
|- Unittests
|- __init__.py
|- man1test.py
[〜#〜] second [〜#〜]、(ModuleNotFoundError: No module named 'Soft'
で発生した "from ...Mans import man1
"エラーの場合man1test.py、それに対する文書化された解決策は、man1.pyをsys.path
に追加することですMansはMansTestパッケージの外にあります。 Pythonドキュメントから モジュール検索パス を参照してください。ただし、sys.path
を直接変更したくない場合は、PYTHONPATH
:
sys.path
は次の場所から初期化されます:
- 入力スクリプトを含むディレクトリ(またはファイルが指定されていない場合は現在のディレクトリ)。
PYTHONPATH
(シェル変数PATH
と同じ構文のディレクトリ名のリスト)。- インストールに依存するデフォルト。
[〜#〜] 3番目[〜#〜]、あなたが言ったfrom ...MansTest.SoftLib import Soft
のために、「が容易になりました前述のman1.pyのインポートステートメントで、インポートが機能します。 Soft.SoftLibをman1.pyにインポートする場合は、man1をセットアップする必要があります。 pyを検索してSoft.SoftLibを見つけ、そこに直接インポートします。
そうは言っても、ここで私はそれを機能させました。
man1.py:
from Soft.SoftWork.manModules import *
# no change to import statement but need to add Soft to PYTHONPATH
def foo():
print("called foo in man1.py")
print("foo call module1 from manModules: " + module1())
man1test.py
# no need for "from ...MansTest.SoftLib import Soft" to facilitate importing..
from ...Mans import man1
man1.foo()
manModules.py
def module1():
return "module1 in manModules"
端末出力:
$ python3 -m man.MansTest.Unittests.man1test
Traceback (most recent call last):
...
from ...Mans import man1
File "/temp/man/Mans/man1.py", line 2, in <module>
from Soft.SoftWork.manModules import *
ModuleNotFoundError: No module named 'Soft'
$ PYTHONPATH=$PYTHONPATH:/temp/man/MansTest/SoftLib
$ export PYTHONPATH
$ echo $PYTHONPATH
:/temp/man/MansTest/SoftLib
$ python3 -m man.MansTest.Unittests.man1test
called foo in man1.py
foo called module1 from manModules: module1 in manModules
提案として、おそらくそれらのSoftLibファイルの目的を再考してください。 man1.pyとman1test.pyの間の「ブリッジ」のようなものですか?現在のファイルのセットアップ方法ですが、期待どおりに機能するとは思いません。また、テスト対象コード(man1.py)がテストフォルダー(MansTest)。