Как я могу удержать 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.