Импорт локальной тестовой версии пакета пространства имен Python
Мне интересно, как я могу импортировать локальную тестовую версию пакета пространства имен 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. Интересно, что если я использую действительно старую сборку 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'
Любая помощь будет принята с благодарностью!
1 ответ
Мне удалось воспроизвести это поведение, используя метод 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
Проверка пространства имен с использованием pkg_resources в setuptools
Структура каталогов:
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'