如何阻止 python 加载 'wrong' 包?
How can I keep python from loading the 'wrong' package?
显然,在我们的 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
(在 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 包,即使我有 pytabix
因为它在主 [=21] 中是自己的包=] 目录。 pysam
包也会发生同样的事情。这里有什么想法吗?
您可以尝试将 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
您似乎需要将 pytabix 放在 sys.path 中较早出现的目录中,或者将 CrossMap 移动到路径下方的目录中。
我喜欢偏爱 pytabix 的想法。如果可以:
- 修改您的 shell (/etc/bash.bashrc) 的系统配置文件以包含如下内容:
export PYTHONPATH=$HOME/stuff/onpythonpath
- 使用
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']
您可以使用 python 版本的 site-packages
文件夹中的 .pth
文件为用户手动排序 sys.path
。 easy_install
也使用它向您的路径添加鸡蛋内容。
导入任何模块时,它首先会查看当前目录,
之后它开始查看系统路径,按照它们出现的顺序(时间顺序),
使用 :
检查
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
.[=16= 提供的部分隔离]
我不知道你是否熟悉virtualenv
,但它的问题是它只提供python级别的隔离。对于依赖于系统库的 python 包,仅隔离这些包的 python 级部分。 tabix
和 pysam
似乎都具有系统级依赖性。因此,创建一个没有安装 CrossMap
的干净虚拟环境应该可以解决问题。
这对您来说是否真的是一个可行的解决方案是另一回事。我只是想我会提出我的两分钱,因为其他提议的解决方案似乎不适合您。我也只是个人认为,与乱用 sys.path 或手动设置模块以指向某些文件相比,这是解决您问题的更好、更清晰的解决方案。
Vagrant 非常容易设置,并且是整个团队在同一环境中工作的一种非常简单的方法,使用他们习惯的主机上的自己的工具。有关详细信息,请参阅 http://docs.vagrantup.com/v2/getting-started/index.html。
显然,在我们的 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
(在 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 包,即使我有 pytabix
因为它在主 [=21] 中是自己的包=] 目录。 pysam
包也会发生同样的事情。这里有什么想法吗?
您可以尝试将 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
您似乎需要将 pytabix 放在 sys.path 中较早出现的目录中,或者将 CrossMap 移动到路径下方的目录中。
我喜欢偏爱 pytabix 的想法。如果可以:
- 修改您的 shell (/etc/bash.bashrc) 的系统配置文件以包含如下内容:
export PYTHONPATH=$HOME/stuff/onpythonpath
- 使用
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']
您可以使用 python 版本的 site-packages
文件夹中的 .pth
文件为用户手动排序 sys.path
。 easy_install
也使用它向您的路径添加鸡蛋内容。
导入任何模块时,它首先会查看当前目录, 之后它开始查看系统路径,按照它们出现的顺序(时间顺序), 使用 :
检查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
.[=16= 提供的部分隔离]
我不知道你是否熟悉virtualenv
,但它的问题是它只提供python级别的隔离。对于依赖于系统库的 python 包,仅隔离这些包的 python 级部分。 tabix
和 pysam
似乎都具有系统级依赖性。因此,创建一个没有安装 CrossMap
的干净虚拟环境应该可以解决问题。
这对您来说是否真的是一个可行的解决方案是另一回事。我只是想我会提出我的两分钱,因为其他提议的解决方案似乎不适合您。我也只是个人认为,与乱用 sys.path 或手动设置模块以指向某些文件相比,这是解决您问题的更好、更清晰的解决方案。
Vagrant 非常容易设置,并且是整个团队在同一环境中工作的一种非常简单的方法,使用他们习惯的主机上的自己的工具。有关详细信息,请参阅 http://docs.vagrantup.com/v2/getting-started/index.html。