简体   繁体   English

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

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

I am wondering how I can import a local testing version of a Python 2.7 namespace package.我想知道如何导入 Python 2.7 命名空间包的本地测试版本。 In this example the package Ska.engarchive is a namespace package under the Ska root.在此示例中,包Ska.engarchiveSka根下的命名空间包。 (This structure is forced on me by legacy). (这种结构是遗留给我的)。

This example shows that even after setting sys.path to start with the local directory, the installed version of the package gets imported, not the local version.此示例表明,即使将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'

I think the problem is related to the way namespace packages are implemented in Python 2, and somehow the namespace paths are always at the front of the list no matter what.我认为这个问题与 Python 2 中命名空间包的实现方式有关,无论如何命名空间路径总是位于列表的前面。 But maybe there is some workaround?但也许有一些解决方法? I spent some time digging around the site package docs, but maybe I just didn't see the right thing.我花了一些时间挖掘site包文档,但也许我只是没有看到正确的内容。

The above example is using the Anaconda Python distribution.上面的示例使用的是 Anaconda Python 发行版。 Interestingly if I use a really old build of Python from ActiveState, the example has the desired outcome of importing the local package:有趣的是,如果我使用 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'

Any help would be hugely appreciated!任何帮助将不胜感激!

I was able to replicate this behavior using setuptools's method for namespace packages (but not the standard pkgutil method ).我能够使用 setuptools 的命名空间包方法(但不是标准的pkgutil 方法)复制这种行为。 Setuptools will import the installed package while pkgutil will import the local package. Setuptools 将导入已安装的包,而pkgutil将导入本地包。 Setuptools appears to load __path__ backwards from what you would expect (installed first, local second). Setuptools 似乎从您所期望的(首先安装,第二个本地)向后加载__path__ Eg, (see example at bottom for definition of nstest)例如, (参见底部示例以了解 nstest 的定义)

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

The way to get around this is to add your local package in the front of __path__ to the right-most namespace package.解决这个问题的方法是将__path__前面的本地包添加到最右侧的命名空间包中。 Eg,例如,

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

Since you say in your question that Ska.engarchive is a namespace package, in your interpreter you want to do the following:由于您在问题中说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

Namespace test using setuptools's pkg_resources使用 setuptools 的pkg_resources 进行命名空间测试

Directory structure:目录结构:

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

nstest.foo/setup.py : nstest.foo/setup.py

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

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

__import__('pkg_resources').declare_namespace(__name__)

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

# empty

Install:安装:

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

Test:测试:

$ 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