2

Python 2.7 名前空間パッケージのローカル テスト バージョンをインポートする方法を知りたいです。この例では、パッケージはルートSka.engarchiveの下の名前空間パッケージです。Ska(この構造は、レガシーによって強制されています)。

この例はsys.path、ローカル ディレクトリから開始するように設定した後でも、パッケージのローカル バージョンではなく、インストールされているバージョンがインポートされることを示しています。

Python 2.7.9 |Continuum Analytics, Inc.| (default, Apr 14 2015, 12:54:25)
... 
In [1]: import sys
In [2]: sys.path.insert(0, '.')
In [3]: import Ska.engarchive.fetch_eng as fetch
In [4]: fetch.__file__
Out[4]: '/proj/sot/ska/arch/x86_64-linux_CentOS-5/lib/python2.7/site-packages/Ska.engarchive-0.36.2-py2.7.egg/Ska/engarchive/fetch_eng.pyc'

この問題は、Python 2 での名前空間パッケージの実装方法に関連していると思います。どういうわけか、名前空間パスは常にリストの先頭にあります。しかし、おそらくいくつかの回避策がありますか?パッケージのドキュメントを掘り下げるのに時間を費やしましたsiteが、適切なものが見つからなかっただけかもしれません。

上記の例では、Anaconda Python ディストリビューションを使用しています。興味深いことに、ActiveState の非常に古いビルドの Python を使用すると、この例ではローカル パッケージをインポートするという望ましい結果が得られます。

Python 2.7.1 (r271:86832, Feb  7 2011, 11:30:54) 

In [1]: import sys
In [2]: sys.path.insert(0, '.')
In [3]: import Ska.engarchive.fetch_eng as fetch
In [4]: fetch.__file__
Out[4]: './Ska/engarchive/fetch_eng.pyc'

どんな助けでも大歓迎です!

4

1 に答える 1

2

名前空間パッケージの setuptools のメソッドを使用して、この動作を再現できました(ただし、標準のpkgutil メソッドではありません)。setuptools はインストール済みパッケージをインポートし、pkgutilはローカル パッケージをインポートします。Setuptools__path__は、予想されるものから逆方向にロードされるように見えます (最初にインストールされ、2 番目にローカルにインストールされます)。例: (nstest の定義については、下部の例を参照してください)

>>> import nstest
>>> nstest.__path__
['/home/caleb/.local/lib/python2.7/site-packages/nstest.foo-0.0.0-py2.7.egg/nstest', 'nstest']

これを回避する方法は、ローカル パッケージを__path__一番右の名前空間パッケージの前に追加することです。例えば、

>>> import nstest
>>> nstest.__path__.insert(0, 'nstest')
>>> from nstest import foo
>>> foo.__file__
'nstest/foo/__init__.py'

質問でSka.engarchive名前空間パッケージだと言っているので、インタープリターで次のことを行います。

>>> import Ska.engarchive
>>> Ska.engarchive.__path__.insert(0, 'Ska/engarchive')
>>> import Ska.engarchive.fetch_eng as fetch
>>> fetch.__file__
'Ska/engarchive/fetch_eng.pyc' # This should be outputted

setuptools のpkg_resourcesを使用した名前空間テスト

ディレクトリ構造:

nstest.foo/
├─ setup.py
└─ nstest/
   ├─ __init__.py
   └─ foo/
      └─ __init__.py

nstest.foo/setup.py :

from setuptools import setup, find_packages
setup(name='nstest.foo', packages=find_packages())

nstest.foo/nstest/__init__.py :

__import__('pkg_resources').declare_namespace(__name__)

nstest.foo/nstest/foo/__init__.py :

# empty

インストール:

$ python2 setup.py build
$ python2 setup.py install --user

テスト:

$ python2
>>> from nstest import foo
>>> foo.__file__
'/home/caleb/.local/lib/python2.7/site-packages/nstest.foo-0.0.0-py2.7.egg/nstest/foo/__init__.pyc'
于 2015-09-13T04:36:35.753 に答える