TL; DR:
Python 3.3では、何もする必要はありません__init__.py
。名前空間パッケージディレクトリに何も配置しないでください。これで問題なく動作します。3.3より前のバージョンでは、将来性があり、暗黙の名前空間パッケージと既に互換性があるためpkgutil.extend_path()
、pkg_resources.declare_namespace()
1 つよりもソリューションを選択してください。
Pythonの3.3を発表、暗黙的な名前空間のパッケージは、参照PEP 420。
これは、によって作成できるオブジェクトのタイプが3つあることを意味しますimport foo
。
foo.py
ファイルで表されるモジュール
- ファイル
foo
を含むディレクトリで表される通常のパッケージ__init__.py
- ファイル
foo
なしの1つ以上のディレクトリで表される名前空間パッケージ__init__.py
パッケージもモジュールですが、ここで「モジュール」と言うときは「非パッケージモジュール」を意味します。
まずsys.path
、モジュールまたは通常のパッケージをスキャンします。成功すると、検索を停止し、モジュールまたはパッケージを作成して初期化します。モジュールも通常のパッケージも見つからなかったが、少なくとも1つのディレクトリが見つかった場合は、名前空間パッケージを作成して初期化します。
モジュールと通常のパッケージは__file__
、.py
作成元のファイルに設定されています。通常のパッケージと名前空間パッケージは__path__
、作成元のディレクトリに設定されています。
あなたが行う場合はimport foo.bar
、上記の検索をするために最初に発生したfoo
パッケージが見つかった場合、その後、の検索bar
で行われるfoo.__path__
代わりの検索パスとしてsys.path
。場合がfoo.bar
発見され、foo
そしてfoo.bar
作成され、初期化されます。
では、通常のパッケージと名前空間パッケージはどのように混在するのでしょうか。通常はそうではありませんが、古いpkgutil
明示的な名前空間パッケージメソッドは、暗黙的な名前空間パッケージを含むように拡張されています。
次の__init__.py
ような既存の通常のパッケージがある場合:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
...従来の動作は、検索されたパスに他の通常のパッケージを追加すること__path__
です。しかし、Python 3.3では、名前空間パッケージも追加されます。
したがって、次のディレクトリ構造を持つことができます。
├── path1
│ └── package
│ ├── __init__.py
│ └── foo.py
├── path2
│ └── package
│ └── bar.py
└── path3
└── package
├── __init__.py
└── baz.py
...そして限り、2のように__init__.py
持ってextend_path
行を(とpath1
、path2
そしてpath3
自分の中にあるsys.path
)import package.foo
、import package.bar
およびimport package.baz
すべての作業はなります。
pkg_resources.declare_namespace(__name__)
暗黙的な名前空間パッケージを含むように更新されていません。