14

distributed の Namespace Packagesから、名前空間パッケージを利用して、大きな Python パッケージをいくつかの小さなパッケージに分割できることがわかりました。本当にすごいです。ドキュメントには次のことも記載されています。

ところで、プロジェクトのソース ツリーには、通常の Python パッケージ レイアウトで名前空間パッケージの __init__.py ファイル (およびすべての親パッケージの __init__.py) を含める必要があることに注意してください。これらの__init__.py ファイルには次の行が含まれている必要があります。

__import__('pkg_resources').declare_namespace(__name__)

このコードは、名前空間パッケージ機構が動作していること、および現在のパッケージが名前空間パッケージとして登録されていることを確認します。

ディレクトリの階層をパッケージの階層と同じにするメリットはあるのでしょうか? それとも、これは、distribute/setuptools の名前空間パッケージ機能の技術的要件ですか?

元、

サブパッケージfoo.barを提供したいと思います。これにより、次のフォルダー階層を構築し、__init__.py を準備して setup.py を名前空間パッケージとして機能させる必要があります。

~foo.bar/
~foo.bar/setup.py
~foo.bar/foo/__init__.py    <=    one-lined file dedicated to namespace packages
~foo.bar/foo/bar/__init__.py
~foo.bar/foo/bar/foobar.py

私は名前空間パッケージに精通していませんが、1) foo/bar と 2) (ほぼ) 1 行の __init__.py が日常的なタスクであるように見えます。彼らは「これは名前空間パッケージです」といういくつかのヒントを提供しますが、 setup.pyにその情報が既にあると思いますか?

編集:

次のブロックに示されているように、ネストされたディレクトリがなく、作業ディレクトリに __init__.py が 1 行しかない名前空間パッケージを作成できますか? つまり、setup.pyに 1 行を追加するだけでそれらを自動的に生成するように依頼できnamespace_packages = ['foo']ますか?

~foo.bar/
~foo.bar/setup.py
~foo.bar/src/__init__.py    <=    for bar package
~foo.bar/src/foobar.py
4

1 に答える 1

45

名前空間パッケージは、主にサブパッケージをインポートするときに特定の効果をもたらします。基本的に、インポート時に何が起こるかは次のとおりですfoo.bar

  • sys.pathインポーターは、次のようなものを探してスキャンしますfoo
  • 何かを見つけると、発見された の内部を調べfooますbar
  • barが見つからない 場合:
    1. fooが通常のパッケージの場合、 anがImportError発生し、foo.bar存在しないことを示します。
    2. foo名前空間パッケージの場合、インポーターはsys.pathの次の一致を探すために戻りfooます。これImportErrorは、すべてのパスが使い果たされた場合にのみ発生します。

それがその機能ですが、なぜそれが必要なのかについては説明していません。大きな便利なライブラリ ( foo) を設計し、その一部として、小さいながらも非常に便利なユーティリティ ( foo.bar) を開発したとします。これは、他の Python プログラマーにとって、より大きなライブラリを使用しない場合でも役立つと考えられます。

それを使用するほとんどの人がサブモジュールのみをインポートする場合でも、パッケージの 1 つの大きな塊として (設計したとおりに) それらを一緒に配布できます。ユーザーは、実際には 10 行のユーティリティ クラスにしか興味がないのに、すべて (全部で 200MB も!) をダウンロードする必要があるため、これは非常に不便です。オープン ライセンスを持っている場合、何人かの人々が最終的にそれをフォークし、今ではユーティリティ モジュールのバージョンが 6 つに分かれていることに気付くでしょう。

fooユーティリティが名前空間の外にあるようにライブラリ全体を書き直すことができます (のbar代わりにfoo.bar)。ユーティリティを個別に配布することができ、一部のユーザーは満足するでしょうが、実際に多くのユーザーがライブラリ全体を使用していることを考えると、それは大変な作業です。新しいものを使用するプログラム。

したがって、本当に必要なのは、foo.bar単独でインストールする方法ですが、それが必要な場合は喜んで共存fooできます。

名前空間パッケージはまさにこれを可能にし、fooパッケージの 2 つの完全に独立したインストールが共存できます。 setuptoolsは、2 つのパッケージが隣り合わせに存在するように設計されていることを認識し、両方がパス上にありfoo、1 つが を含み、もう 1 つがfoo.bar残りの を含むように見えるように、フォルダ/ファイルを丁寧にシフトしますfoo

それぞれに 1 つずつ、 2 つの異なるsetup.pyスクリプトがあります。 foo/__init__.py両方のパッケージで、それらが名前空間パッケージであることを示す必要があるため、インポーターはどちらのパッケージが最初に検出されたかに関係なく続行することを認識しています。

于 2011-12-05T02:51:25.970 に答える