Python 排序sys.path:首先是virtualenv,然后是/usr
为什么Python 排序sys.path:首先是virtualenv,然后是/usr,python,path,pip,virtualenv,Python,Path,Pip,Virtualenv,为什么sys.path在my virtualenv的目录之前包含/usr/… 我使用--系统站点包创建virtualenv 此时,sys.path看起来像这样: /home/my-virtualenv/src/foo /usr/lib/python2.7/site-packages <--- /usr paths should be below /usr/lib64/python2.7/site-packages /home/my-virtualenv/lib/python
sys.path
在my virtualenv的目录之前包含/usr/…
我使用--系统站点包创建virtualenv
此时,sys.path
看起来像这样:
/home/my-virtualenv/src/foo
/usr/lib/python2.7/site-packages <--- /usr paths should be below
/usr/lib64/python2.7/site-packages
/home/my-virtualenv/lib/python27.zip
/home/my-virtualenv/lib64/python2.7
/home/my-virtualenv/lib64/python2.7/plat-linux2
/home/my-virtualenv/lib64/python2.7/lib-tk
/home/my-virtualenv/lib64/python2.7/lib-old
/home/my-virtualenv/lib64/python2.7/lib-dynload
/usr/lib64/python2.7
/usr/lib/python2.7
/usr/lib64/python2.7/lib-tk
/home/my-virtualenv/lib/python2.7/site-packages
/home/my virtualenv/src/foo
/usr/lib/python2.7/site-packages您可以在模块导入之前简单地预先设置所需的路径。有点黑,但应该能解决你的问题
import sys
sys.path.insert(1, '/home/my-virtualenv/lib/python2.7/site-packages')
import lalala
下面是解决问题的简单方法:
1-打开myvirtualenv/lib/python2.7/site.py
文件进行编辑
2-在此文件末尾追加以下排序算法行(或解决问题的任何代码)(无第一行缩进):
在@Jan Philip Gehrcke建议的代码行下方:
sys.path = sorted(sys.path, key=lambda x: x.startswith(prefix), reverse=True)
3-运行您的程序并享受
此解决方案可帮助您对sys.path
列表进行排序,而无需在程序主体中添加烦人的行
注意:模块在初始化期间自动导入。可以使用解释器的-s
选项禁止自动导入。如果使用交互式shell,则可以设置PYTHONSTARTUP
,或者还可以设置一些bash别名,以您喜欢的方式修改PYTHONPATH
。
您还可以在virtualenv
的bin
目录中修改激活文件activate.csh
,activate\u this.py
;或site.py
文件作为另一个响应
pip+virtualenv
is-正如已经指出的那样,对于系统范围的软件包来说,它不是一个非常友好的组合,也就是说,在构建环境时,使用系统numpy或软件包x,y没有默认标志。尽管正如评论中所建议的那样,我也建议使用--无站点包构建,然后在讨论后从/usr/lib
编辑中专门导入所需内容:
sys.path = sorted(sys.path, key=lambda x: x.startswith(prefix), reverse=True)
“我希望我的virtualenv(/usr…)之外的所有路径都位于
virtualenv的路径。[…]需要对其进行排序。“
然后,只需在第一次导入之前对sys.path
进行排序。给定与virtalenv位置对应的特定路径前缀
,此方法可能足够:
sys.path = sorted(sys.path, key=lambda x: x.startswith(prefix), reverse=True)
sorted()
的排序行为是稳定的:对于具有相同排序键的项目,保留原始顺序。这里只使用两个排序键:True
和False
。你需要想出一个可靠的方法来设置你的前缀(你可能想硬编码它,或者根据当前的工作目录来确定它,我相信你会找到一种方法)
原始答案(通常仍然有效):
sys.path = sorted(sys.path, key=lambda x: x.startswith(prefix), reverse=True)
您不想过多地阐述您的需求和应用程序场景,因此我提供了一个更一般的答案:您可能需要过度思考您的方法,并且可能不希望virtualenv
完全解决您的问题
在某些情况下,virtualenv
并不是完美的解决方案。这是一个折衷方案,本文详细描述了折衷方案的一个方面:
在许多场景中,virtualenv
发挥了出色的作用,工作做得非常出色!当然,这对我帮助很大,尤其是在发展方面。在其他场景中,它不是一个完整的解决方案,甚至是一个糟糕的解决方案
因此,现在我看到了几个不同的选择:
使用virtualenv,但是控制那些你需要改变的事情。例如,在执行特定导入之前,从包中修改sys.path
。虽然有些人可能认为这是“不干净的”,但它确实是一种快速有效地控制目录搜索顺序的方法。code>sys.path.insert(1,foo)
实际上被许多包和测试环境使用。这并不罕见。这种方法可以在工作一分钟后为您提供有效的解决方案。试试看李>
如果您认为您的案例中的virtualenv的行为没有记录在案,或者没有清楚地显示错误行为,那么请向项目报告您的发现。他们一定会感激你的简明反馈
如果您认为virtualenv没有提供应用程序案例中所需的隔离或控制级别,那么您可能希望查看其他选项,例如Docker或Vagrant,或者完全支持虚拟机
我发现解决此问题的一个简单方法是将您的virtualenv site packages文件夹添加到$VIRTUAL_ENV/lib/python2.7/site-packages//virtualenv\u path\u extensions.pth文件中,或者在激活环境后进入shell:
$add2virtualenv$VIRTUAL_ENV/lib/python2.7/site-packages
这将强制将文件夹显示在系统文件夹之前,正如我注意到添加的其他路径一样
我相信这不是最干净的解决方案,但确实virtualenv奇怪地排列了路径
另一个观察结果是,当我启动ipython时,sys.path以合理的顺序出现,但是当python解释器内部出现时,我不知道为什么。“我不能在我的上下文中使用——没有站点包”
:请详细说明。@Kevin我可以解释,但会有什么变化?我不能使用——在我的上下文中没有站点包——就是这样。问题是如何对sys.path进行排序:-)坦率地说,--系统站点包
已损坏。在virtualenv中安装所有内容几乎总是更好的。您的情况(显然)不同,这使得我很难在没有更多信息的情况下给您一个有用的答案。这种限制(无--无站点包
)是因为一些共享的全局包吗?如果是这样,为什么不在virtualenv中复制它们呢?我更新了这个问题,并在cetain中添加了“为什么我使用系统站点包”一节