如何阻止 python 加载 'wrong' 包?



显然,在我们的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加载。现在,即使I pip install pytabix(它在site-packages目录中创建了一个tabix.so文件),它仍然会达到CrossMap版本。我甚至尝试用pip install --user pytabix安装pytabix本地,但它仍然加载CrossMap版本。

如何将import tabix指向tabix.so文件而不是CrossMap的子包?

更新:即使在将CrossMap移动到"old_versions"目录后,当我尝试加载tabix时,它仍然会遇到一个不同的包,该包将tabix作为子包。当我import tabix然后运行tabix时,我从RSeQC-2.6.1得到一个pysam包,尽管我在主site-packages目录中有pytabix作为它自己的包。pysam软件包也发生了同样的情况。有什么想法吗?

您可以使用python版本的site-packages文件夹中的.pth文件为用户手动排序sys.patheasy_install也会使用它来将鸡蛋内容添加到您的路径中。

您似乎需要将pytabix放在sys.path中较早出现的目录中,或者将CrossMap移到路径后面的目录中。

我喜欢喜欢吡塔麦的想法。如果可以:

  1. 修改shell的系统配置文件(/etc/bash.bashrc),以包含以下内容:export PYTHONPATH=$HOME/stuff/onpythonpath
  2. 使用pip install --target="$HOME/stuff/onpythonpath" pytabix

修改系统范围的配置文件应该很早就将新路径放入sys.path中。

喜欢pytabix的另一种方式是以可编辑模式安装它。在我的系统中,它的效果是将新安装的包首先放在sys.path:中

例如:我之前的路径(包括通过在配置文件中导出PYTHONPATH添加的"onpythonpath"):

 ['',
  '/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/pytabix.git@40e7a78ba6fdfbf72a25da718f530e7c1bad389e#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']

您可以尝试将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 一样导入

导入任何模块时,都会首先查找当前目录,然后它开始查看系统路径,检查使用:

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()

希望这能有所帮助。

我建议您在项目中使用virtualenv。Virtualenv是一种很好的方法,可以避免命名空间污染和像您这样的争用。

要调试不知道特定模块隐藏在哪里的情况,可以尝试在交互式Python shell中导入特定模块,并打印该模块的__file__属性。虽然不能在所有情况下都工作,例如压缩模块,但可以让您开始工作。

据我所见,解决这个问题最干净的方法是由Vagrant等虚拟机管理程序提供的完全隔离,而不是由virtualenv提供的部分隔离。

我不知道你是否熟悉virtualenv,但它的问题是它只提供python级别的隔离。对于依赖于系统库的python包,只有这些包的python级别部分是隔离的。tabixpysam似乎都具有系统级依赖关系。因此,在没有安装CrossMap的情况下创建一个干净的虚拟环境应该可以解决这个问题。

这对你来说是否真的是一个可行的解决方案,那就另当别论了。我只是觉得我应该提出我的两分钱,因为其他提出的解决方案似乎对你不起作用。我个人也认为,这是一个更好、更干净的解决方案,而不是扰乱sys.path或手动设置模块指向某些文件。

Vagrant非常容易设置,对于整个团队来说,使用他们习惯的主机上的工具在同一环境中工作是一种非常简单的方式http://docs.vagrantup.com/v2/getting-started/index.html了解更多详细信息。

最新更新