6

パッケージ名を共有する 2 つの個別のプロジェクトがあります。それらは両方とも PYTHONPATH にない限り問題なく実行されますが、両方が表示されるとすぐに、そのうちの 1 つが自身のプロジェクトでインポートを見つけることができなくなります。

例、次のような 2 つのプロジェクト:

プロジェクト 1:

x/
  __init__.py
  test.py
  foo.py

test.py には次の行が含まれています。

import x.foo

プロジェクト 2:

x/
  __init__.py
  bar.py

私が走れば

PYTHONPATH=. python x/y/test.py

エラーはありません。しかし、私が実行すると

PYTHONPATH='pathtoproject2:.' python x/test.py

エラーが発生します:

Traceback (most recent call last):
  File "x/test.py", line 1, in <module>
    import x.foo
ImportError: No module named foo

共通のパッケージを持つ異なる Python プロジェクトで PYTHONPATH を共有する方法はありますか? それとも、Python は常にパッケージが見つかった最初のパスのみを使用しますか?

注: インポートを x.foo からインポート foo に変更すると、機能することがわかっています。しかし、どちらのパッケージも変更せずに実行できるかどうかを知りたいです。

4

2 に答える 2

4

インポート メカニズムではネイティブにサポートされていませんが、Python で名前空間付きパッケージを作成するための回避策があります。次のコードを両方の __init__.py ファイルに配置するだけです。

try:
    import pkg_resources
    pkg_resources.declare_namespace(__name__)
except ImportError:
    import pkgutil
    __path__ = pkgutil.extend_path(__path__, __name__)

pkg_resourcesは setuptools python パッケージによって提供され、egg zip ファイルに含まれるパッケージも処理できるという利点があります。

pkgutilは python の標準ライブラリに含まれているため、システムに setuptools がインストールされていない場合、名前空間拡張を処理するために pkgutil に依存しています。

Python 名前空間パッケージの詳細については、次の場所にあります。

http://packages.python.org/distribute/setuptools.html#namespace-packages

http://www.python.org/dev/peps/pep-0382/

于 2012-01-27T23:31:46.847 に答える
3

現在、Python は異なるディレクトリからのパッケージをサポートしていません。パッケージは単なる名前空間ではなく、ユニットです。これは、Java の「パッケージ」や、より適切な名前の .NET の「名前空間」とは異なります。

パッケージをインポートするとき、Python はsys.pathを順番にスキャンし、最初に一致したものを使用します。パスの後ろにあるディレクトリに、名前が一致する別のモジュールまたはパッケージがある場合、それらは見つかりません。

ちなみに、あなたの「メモ」は真実ではありません。を使用するimport fooと、Python は のディレクトリ内で相対インポートを試行し、一致するものが見つからない場合、どちらも存在しないtest.pymodule の絶対インポートを試行し、 .fooImportError

パッケージ名を使用して共通の接頭辞を使用してモジュールをグループ化する代わりに、パッケージを小規模で自己完結型のライブラリと考えてください。Python では、ネストされた よりもフラットな方が優れており、1 つの大きなモノリシック パッケージよりも、それぞれが 1 つの異なる目的を果たす複数のトップレベル パッケージを使用する方が望ましいです。andの代わりに、org.example.fooandorg.example.barを使用fooしてbarください。

于 2011-08-25T08:02:18.780 に答える