[解決済み] Pythonで名前空間パッケージを作成するにはどうすればよいですか?
質問
Pythonでは、名前空間パッケージを使用すると、Pythonのコードを複数のプロジェクトに分散させることができます。これは、関連するライブラリを別々のダウンロードとしてリリースしたい場合に便利です。例えば、ディレクトリ
Package-1
と
Package-2
で
PYTHONPATH
,
Package-1/namespace/__init__.py
Package-1/namespace/module1/__init__.py
Package-2/namespace/__init__.py
Package-2/namespace/module2/__init__.py
エンドユーザは
import namespace.module1
と
import namespace.module2
.
複数のPython製品がその名前空間のモジュールを定義できるように、名前空間パッケージを定義する最良の方法は何でしょうか?
どのように解決するのですか?
TL;DR。
Python 3.3 では、何もする必要はありません。
__init__.py
を名前空間パッケージのディレクトリに配置すれば、そのまま動作します。3.3 より前のバージョンでは
pkgutil.extend_path()
という解決策を
pkg_resources.declare_namespace()
は、将来性があり、暗黙的な名前空間パッケージとすでに互換性があるからです。
Python 3.3では暗黙の名前空間パッケージが導入され、以下のようになります。 PEP 420 .
これはつまり、現在では
import foo
:
-
で表されるモジュールは
foo.py
ファイル -
通常のパッケージで、ディレクトリで表される
foo
を含む__init__.py
ファイル -
1つまたは複数のディレクトリで表される名前空間パッケージ
foo
を一切使用せず__init__.py
ファイル
パッケージもモジュールですが、ここで言うモジュールとは、quot;非パッケージモジュールという意味です。
最初にスキャンするのは
sys.path
を指定します。もし成功したら、検索をやめて、モジュールやパッケージを作成し、初期化します。モジュールや通常のパッケージは見つからなかったが、少なくとも一つのディレクトリが見つかった場合、名前空間パッケージを作成し、初期化する。
モジュールと通常のパッケージは
__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__)
は、暗黙の名前空間パッケージを含むように更新されていません。
関連
-
[解決済み】pygame.error: ビデオシステムが初期化されていない
-
[解決済み】numpy: true_divide で無効な値に遭遇
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] Pythonで2つのリストを連結する方法は?
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] インストールされているnpmパッケージのバージョンを検索する
-
[解決済み] usingディレクティブはネームスペースの内側と外側のどちらを使うべきですか?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】Pythonに三項条件演算子はありますか?
-
[解決済み】2つの辞書を1つの式でマージする(辞書の和をとる)には?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Python 可視化 big_screen ライブラリ サンプル 詳細
-
Pythonを使って簡単なzipファイルの解凍パスワードを手作業で解く
-
PythonによるExcelファイルの一括操作の説明
-
[解決済み] _tkinter.TclError: 表示名がなく、$DISPLAY環境変数もない。
-
[解決済み】Pythonスクリプトで「Expected 2D array, got 1D array instead: 」というエラーが発生?
-
[解決済み】TypeErrorを取得しました。エントリを持つ子テーブルの後に親テーブルを追加しようとすると、 __init__() missing 1 required positional argument: 'on_delete'
-
[解決済み】"No JSON object could be decoded "よりも良いエラーメッセージを表示する。
-
[解決済み】Python elifの構文が無効です【終了しました
-
[解決済み】Flask ImportError: Flask という名前のモジュールがない
-
[解決済み】Python - "ValueError: not enough values to unpack (expected 2, got 1)" の修正方法 [閉店].