繁体   English   中英

导入 Python 命名空间包的本地测试版本

[英]Import local testing version of a Python namespace package

我想知道如何导入 Python 2.7 命名空间包的本地测试版本。 在此示例中,包Ska.engarchiveSka根下的命名空间包。 (这种结构是遗留给我的)。

此示例表明,即使将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'

任何帮助将不胜感激!

我能够使用 setuptools 的命名空间包方法(但不是标准的pkgutil 方法)复制这种行为。 Setuptools 将导入已安装的包,而pkgutil将导入本地包。 Setuptools 似乎从您所期望的(首先安装,第二个本地)向后加载__path__ 例如, (参见底部示例以了解 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'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM