Как я могу удержать python от загрузки "неправильного" пакета?
Существует, по-видимому, пакет, загруженный в нашу среду Python/2.7.2
с именем CrossMap
, которая имеет в качестве подпакета tabix
. Когда я запускаю эту версию python и import tabix
, tabix
показывает: /hpcf/apps/python/install/2.7.2/lib/python2.7/site-packages/CrossMap-0.1.6-py2.7-linux-x86_64.egg/tabix/__init__.pyc
Указывает, что она загружается из CrossMap
. Теперь, даже если я pip install pytabix
(который создает файл tabix.so
в каталоге site-packages
), он по-прежнему попадает в версию CrossMap
. Я даже попытался установить pytabix
localling с помощью pip install --user pytabix
, но он все еще загружает версию CrossMap
.
Как я могу указать import tabix
в файл tabix.so
вместо подпакета CrossMap
?
UPDATE: даже после перемещения CrossMap
в каталог old_versions, когда я пытаюсь загрузить tabix
, он по-прежнему попадает в другой пакет, который имеет tabix
в качестве подпакета. Когда я import tabix
, а затем запустите tabix
, я получаю пакет pysam из RSeQC-2.6.1
, хотя у меня есть pytabix
как его собственный пакет в основном каталоге site-packages
. То же самое происходит с пакетом pysam
. Любые идеи здесь?
Ответы
Ответ 1
Кажется, вам нужно будет поместить pytabix в каталог, который встречается ранее в sys.path, или переместить CrossMap в каталог далее по пути.
Мне нравится понятие предпочтения pytabix. Если бы вы могли:
- Измените файл конфигурации системы для вашей оболочки (/etc/ bash.bashrc), чтобы включить что-то вроде следующего:
export PYTHONPATH=$HOME/stuff/onpythonpath
- Используйте
pip install --target="$HOME/stuff/onpythonpath" pytabix
Изменение общесистемного конфигурационного файла должно положить новый путь довольно рано в sys.path
.
Еще один способ отдать предпочтение pytabix - установить его в редактируемый режим. В моей системе, которая сначала помещает недавно установленный пакет в sys.path:
Пример:
Мой путь до (который включает в себя "onpythonpath", добавленный путем экспорта PYTHONPATH в файл конфигурации):
['',
'/usr/local/bin',
'/home/keith/devel/onpythonpath',
'/usr/lib/python2.7',
'/usr/lib/python2.7/plat-x86_64-linux-gnu',
'/usr/lib/python2.7/lib-tk',
'/usr/lib/python2.7/lib-old',
'/usr/lib/python2.7/lib-dynload',
'/usr/local/lib/python2.7/dist-packages']
Теперь после запуска:
pip install -e git+https://github.com/slowkow/[email protected]#pytabix
Это мой путь:
['',
'/usr/local/bin',
'/home/keith/src/pytabix',
'/home/keith/devel/onpythonpath',
'/usr/lib/python2.7',
'/usr/lib/python2.7/plat-x86_64-linux-gnu',
'/usr/lib/python2.7/lib-tk',
'/usr/lib/python2.7/lib-old',
'/usr/lib/python2.7/lib-dynload',
'/usr/local/lib/python2.7/dist-packages']
Ответ 2
Вы можете использовать файл .pth
в папке python version site-packages
, чтобы вручную отсортировать sys.path
для пользователя. easy_install
использует это, чтобы добавить содержимое яйца на ваш путь.
Ответ 3
Вы можете установить pytabix
в другую папку pip install --target="/path/to/your_new_path" pytabix
и добавить новый путь к sys.path
:
import sys
sys.path.insert(0, "/path/to/your_new_path")
а затем импортируйте как import your_new_path.tabix
Ответ 4
Когда какой-либо модуль импортируется, он сначала обращается к текущему каталогу,
после этого он начинает искать системный путь, что в порядке их появления (хронологический порядок),
проверьте с помощью:
import sys
print sys.path
Итак, подход новичков будет обменивать элементы списка и помещать путь туда, где нам нужно сначала импортировать, в 0-й индекс (обменивать список)
Вышеизложенное может быть сделано для понимания концепции. (никогда не было хорошего подхода к реальной реализации)
или если вы можете добавить путь до импорта
import sys
# the PackageFolder dir contains foo.py, bar.py
sys.path.append('/foo/bar/PackageFolder')
from foo import ChocolateClass
from bar import RunClass,WalkClass
В более лучшем подходе указывается путь, из которого вы хотите импортировать модуль:
import bar
foo = bar.load_source('module.name', '/path/to/file.py')
foo.MyClass()
Существуют эквивалентные функции удобства для скомпилированных файлов Python и DLL.
Для Python 3.3+ это, к сожалению, немного более важно:
import importlib.bar
loader = importlib.bar.SourceFileLoader("module.name", "/path/to/file.py")
foo = loader.load_module()
foo.MyClass()
Надеюсь, что это поможет.
Ответ 5
Я бы предложил вам использовать virtualenv для вашего проекта. Virtualenv - отличный способ избежать загрязнения пространства имен и конфликтов, подобных тем, которые у вас есть.
Чтобы отладить ситуацию, когда вы не знаете, где скрывается конкретный модуль, вы можете попробовать импортировать конкретный модуль в интерактивную оболочку Python и напечатать свойство __file__
для модуля. Не работает во всех случаях, например, zipped modules, но вы можете начать работу.
Ответ 6
Насколько я вижу, самым чистым способом решения этой проблемы является полная изоляция, обеспечиваемая гипервизором виртуальной машины, таким как Vagrant, в отличие от частичной изоляции, предоставляемой virtualenv
.
Я не знаю, знакомы ли вы с virtualenv
, но проблема заключается в том, что он обеспечивает только изоляцию на уровне python. Для пакетов python, зависящих от системных библиотек, выделяется только часть уровня этих компонентов на уровне python. Оба tabix
и pysam
, похоже, имеют зависимости уровня системы. Таким образом, создание чистой виртуальной среды без CrossMap
должно решить проблему.
Действительно ли это реальное решение для вас - это совсем другая история. Я просто подумал, что я выдвинул свои два цента, поскольку другие предлагаемые решения, похоже, не работают для вас. Я также лично считаю, что это лучшее и более чистое решение вашей проблемы, чем возиться с sys.path или вручную устанавливать модули, чтобы указывать на определенные файлы.
Vagrant очень легко настроить, и это действительно простой способ для всей команды работать в одной и той же среде, используя свои собственные инструменты с их хост-машины, к которой они привыкли. Подробнее см. http://docs.vagrantup.com/v2/getting-started/index.html.