为什么sys.path
在我的virtualenv目录之前包含/usr/...
?
我用--system-site-packages
目前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
我希望我的virtualenv(/usr...
)之外的所有路径都低于virtualenv的路径。
否则会发生疯狂的事情:我用pip安装一个软件包。 Pip告诉我安装了新版本(pip freeze | grep -i ...
),但导入确实使用了/usr/lib/python2.7/site-packages
我不能在我的上下文中使用--no-site-packages
。
有没有办法对sys.path
进行排序?
为什么我使用system-site-packages
似乎没有直接的方法可以从virtualenv中提供的全局站点包中创建单个库。看到这个问题: make some modules from global site-packages available in virtualenv
像python-gtk这样的软件包很难在virtualenv中安装。
答案 0 :(得分:2)
您可以在模块导入之前简单地添加所需的路径。有点hacky,但应该解决你的问题
import sys
sys.path.insert(1, '/home/my-virtualenv/lib/python2.7/site-packages')
import lalala
答案 1 :(得分:2)
在讨论后编辑:
&#34;我希望我的virtualenv(/ usr ...)之外的所有路径都低于 virtualenv的路径。 [...]需要对其进行排序。&#34;
然后,只需在第一次导入之前对sys.path
进行排序。给定与您的virtalenv位置相对应的特定路径prefix
,这种方法可能就足够了:
sys.path = sorted(sys.path, key=lambda x: x.startswith(prefix), reverse=True)
sorted()
的排序行为是稳定的:对具有相同排序键的项目保留原始顺序。此处仅使用了两个排序键:True
和False
。您需要提出一种可靠的方法来设置prefix
(您可能希望对其进行硬编码,或者根据当前工作目录确定它,我相信您找到了办法)。
原始答案(通常仍然有效):
您不想过多地详细说明您的要求和应用场景,因此我提供了一个更一般的答案:您可能需要过度思考您的方法,并且可能不希望virtualenv
完全解决您的问题。< / p>
在某些情况下,virtualenv
不是完美的解决方案。它是的折衷方案,本文详尽描述了这种妥协的一方:https://pythonrants.wordpress.com/2013/12/06/why-i-hate-virtualenv-and-pip/
在许多情况下,virtualenv
有着出色的目的,并且工作得非常好!它确实给了我很多帮助,特别是对于开发目的。在其他情况下,它要么不是一个完整的解决方案,要么是一个糟糕的解决方案。
所以,我现在有几个不同的选择:
sys.path
。虽然有些人可能会考虑这个&#34;不干净&#34;,但它确实是一种快速有效地控制目录搜索顺序的方法。 许多包和测试环境实际上使用sys.path.insert(1, foo)
。这根本不常见。这种方法可以在一分钟的工作后为您提供工作解决方案。试一试!答案 2 :(得分:1)
如果您使用的是互动式外壳,则可以设置PYTHONSTARTUP
,或者设置一些bash别名,以您喜欢的方式修改PYTHONPATH
。
您还可以修改activate.csh
的{{1}}目录中的激活文件activate_this.py
,bin
;或virtualenv
文件作为另一个提到的回复。
site.py
- 因为已经指出系统级软件包不是一个非常友好的组合,即没有默认标志用于说使用system numpy 或包x,y 在构建环境时。虽然正如评论中所建议的那样,我也建议使用pip + virtualenv
构建,然后从--no-site-packages
答案 3 :(得分:0)
以下解决方案解决您的问题:
1-打开my-virtualenv/lib/python2.7/site.py
文件进行编辑。
2-在此文件末尾附加排序算法(或解决问题的任何代码)的下方行(没有第一行缩进):
prefix = __file__.rsplit(os.sep, 3)[0]
以下代码行建议@ Jan-Philip Gehrcke:
sys.path = sorted(sys.path, key=lambda x: x.startswith(prefix), reverse=True)
3-运行程序并享受
此解决方案可帮助您对sys.path
列表进行排序,而不会在程序正文中添加恼人的行。
注意:初始化期间会自动导入site模块。可以使用解释器的-S
选项来禁止自动导入。
答案 4 :(得分:0)
我发现解决此问题的一种简单方法就是将virtualenv site-packages文件夹添加到$ VIRTUAL_ENV / lib / python2.7 / site-packages / _virtualenv_path_extensions.pth文件中,或者在激活环境后输入shell :
$ add2virtualenv $VIRTUAL_ENV/lib/python2.7/site-packages
这会强制显示系统文件夹之前的文件夹,因为我注意到它添加了其他路径。
我相信这不是最干净的解决方案,但事实上,virtualenv奇怪地命令道路。
另一个观察是当我启动ipython时,sys.path以合理的顺序出现,但是当在python解释器内部没有时,不知道为什么。