web-dev-qa-db-ja.com

`__import __( 'pkg_resources')。declare_namespace(__ name __)`は何をしますか?

一部の__init__.pyそのような1行を見たモジュールのファイル:

__import__('pkg_resources').declare_namespace(__name__)

それは何をし、なぜ人々はそれを使うのですか?実行時の動的なインポートと名前空間の作成に関連するとします。

51
rsk

要約すると、次の2つです。

  1. ___import___は、Python関数であり、パッケージの名前として文字列を使用してパッケージをインポートします。インポートされたパッケージを表す新しいオブジェクトを返します。したがって、foo = __import__('bar')は、barという名前のパッケージをインポートし、そのオブジェクトへの参照をローカルオブジェクト変数fooに格納します。

  2. Setup utils pkg_resources ' のドキュメントから、declare_namespace() "ドット付きのパッケージ名nameであることを宣言します]含まれるパッケージとモジュールが複数のディストリビューションに分散している可能性がある「名前空間パッケージ」です。

したがって、__import__('pkg_resources').declare_namespace(__name__)は 'pkg_resources'パッケージを一時ファイルにインポートし、その一時ファイルに格納されている_declare_namespace_関数を呼び出します(importステートメントではなく___import___関数が使用されるため、 _pkg_resources_という名前の余分な記号は残っていません。このコードが_my_namespace/__init__.py_にある場合、___name___は_my_namespace_であり、このモジュールは_my_namespace_名前空間パッケージに含まれます。

詳細は setup tools のドキュメントを参照してください

同じ効果を達成するための古いメカニズムの説明については この質問 を参照してください。

Python 3.3。で始まる類似の機能を提供する標準化されたメカニズムについては、 PEP 42 を参照してください。

41
Nathan

これは、Pythonでいわゆる「名前空間パッケージ」を宣言する方法です。

これらは何であり、問​​題は何ですか?

多くの機能を備えたソフトウェア製品を配布し、すべての人々がすべてを望んでいるわけではないので、それをバラバラに分割し、オプションのプラグインとして出荷するとします。

人々ができるようにしたい

_import your_project.plugins.plugin1
import your_project.plugins.plugin2
...
_

つまり、ディレクトリ構造が上記とまったく同じである場合、つまり

_your_project/
    __init__.py
    plugins/
        __init__.py
        plugin1.py
        plugin2.py
_

しかし、これらの2つのプラグインを別々のpythonパッケージとして出荷して、2つの異なるディレクトリに配置する場合はどうでしょうか?次に各パッケージの___init__.py_に__import__('pkg_resources').declare_namespace(__name__)を入れて、Pythonがこれらのパッケージがより大きな「名前空間パッケージ」の一部であることを認識できるようにする場合があります。この場合は_your_project.plugins_。

詳細は documentation を参照してください。

7
Ivan Ivanov