1

Мне интересно, как я могу импортировать локальную тестовую версию пакета пространства имен Python 2.7. В этом примере пакет Ska.engarchive является пакетом пространства имен под корнем Ska. (Эта структура навязана мне по наследству).Импортировать локальную тестовую версию пакета пространства имен Python

В этом примере показано, что даже после установки 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. Интересно, если я использую очень старую сборку Python от ActiveState, пример имеет желаемого результата импорта локального пакета:

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' 

Любая помощь будет очень признателен!

ответ

2

Я смог воспроизвести это поведение, используя метод setuptools для namespace packages (но не стандарт pkgutil method). 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/ __в этом__.ру:

# 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' 
+0

Предложенное исправление работало отлично. Я не понимал, что существует другой способ реализации пакетов пространства имен (с 'pkgutil'), поэтому это двуполезный ответ. –

Смежные вопросы