.
が現在の作業ディレクトリである次のディレクトリ構造があるとします
.
\---foo
\---bar
\---__init__.py
\---baz.py
python -c "import foo.bar.baz"
を実行すると、
Traceback (most recent call last):
File "<string>", line 1
ImportError: No module named foo.bar.baz
私がecho "" > foo/__init__.py
の場合、上記のコマンドは機能します。
私は何か間違ったことをしていますか、それとも__init__.py
のポイントを誤解していますか?私はそれがすべきでない場所に存在するモジュールを停止することだと思いました、例えばstring
という名前のディレクトリですが、私の例でfoo
をstring
に置き換えると、使用してはならないモジュールを作成せざるを得ないようです。階層のより深いファイルを参照します。
更新
私は__init__.py
を生成し、ディレクトリ構造を適用するビルドシステムを使用しています。階層を変更することはできますが、__init__.py
を自分で追加することをお勧めします。質問を少し変更するために、なぜpythonパッケージを最上位ではなくすべてのレベルで必要とするのですか?pythonパスまたはpythonパス?
はい、ディレクトリをモジュールとして扱う場合は、このファイルが必要です。
__init__.py
ファイルは、Pythonディレクトリをパッケージを含むものとして扱うために必要です。これは、文字列などの一般的な名前のディレクトリが、発生する有効なモジュールを誤って非表示にしないようにするために行われます最も単純な場合、__init__.py
は空のファイルにすることができますが、パッケージの初期化コードを実行したり、後で説明する__all__
変数を設定したりすることもできます。
https://docs.python.org/3/tutorial/modules.html#packages
空でない__init__.py
を作成しようとしています。モジュールを文書化し、最初のレベルで最も有用なオブジェクト(クラス/関数)を提供することにより、ユーザー/開発者のネストされたインポートを取り除く可能性が高い... ...実際には可能な限りシンプルに使用する対照的に-としましょう-Java imports
質問の更新後に編集
デフォルトのインポーター/ファインダー(sys.meta_path
を確認)は次のとおりです。
3番目は__init__.py
です(実際にはFrozenImporterも)。
PathFinder
は、sys.path
からのパス(およびパッケージで定義されている__path__
)でモジュールを検索します。モジュールは、スタンドアロンpythonファイル(検索されたパスのルートにある場合)または__init__.py
のディレクトリのいずれかです。
あなたの例を参照してください:
foo/
bar/
__init__.py
baz.py
_init__.py
をfoo/
で作成すると、foo.bar.baz
が使用可能になります(お伝えしたとおり)。
foo/
にsys.path
を追加するか、PYTHONPATH=foo/
を介して渡すと、bar.baz
が使用可能になります(親モジュールfooがないことに注意してください)。
独自の Finder (およびローダー)を作成すると、たとえば、どこにいても必要なファイルをロードできます。それはあなたに大きな力を与えます。たとえば、 stack-overflow-import
を見て、SOの検索結果に基づいてコードを公開します。