对sys.path进行排序:首先是virtualenv,然后是/ usr

gue*_*tli 5 python pip path virtualenv

为什么sys.path包含/usr/...我的virtualenv目录之前?

我创建了virtualenv --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
Run Code Online (Sandbox Code Playgroud)

我希望virtualenv(/usr...)之外的所有路径都低于virtualenv的路径.

否则会发生疯狂的事情:我用pip安装一个软件包.Pip告诉我新版本已安装(pip freeze | grep -i ...)但导入确实使用了一个/usr/lib/python2.7/site-packages

我无法--no-site-packages在我的背景下使用.

有没有办法排序sys.path

为什么我使用system-site-packages

似乎没有直接的方法可以从virtualenv中提供的全局站点包中创建单个库.请参阅此问题: 使用virtualenv中的全局站点包创建一些模块

像python-gtk这样的软件包非常难以在virtualenv中安装.

Jan*_*cke 2

讨论后编辑:

“我希望 virtualenv (/usr...) 之外的所有路径都位于 virtualenv 的路径下方。[...] 需要对其进行排序。”

然后,sys.path在第一次导入发生之前对您进行排序。prefix给定与 virtalenv 位置相对应的特定路径,这种方法可能就足够了:

sys.path = sorted(sys.path, key=lambda x: x.startswith(prefix), reverse=True)
Run Code Online (Sandbox Code Playgroud)

sorted()的排序行为是稳定的:具有相同排序键的项目保留原始顺序。这里,仅使用两个排序键:TrueFalse。您需要想出一种可靠的方法来设置您的prefix(您可能想要对其进行硬编码,或者根据当前工作目录确定它,我相信您会找到一种方法)。

原始答案(一般来说仍然有效):

您不想过多地阐述您的需求和应用场景,因此我提供了一个更笼统的答案:您可能需要过度思考您的方法,并且可能不期望virtualenv完全解决您的问题。

在某些情况下,virtualenv这并不是完美的解决方案。这一种妥协,本文详尽地描述了这种妥协的一方面:https ://pythonrants.wordpress.com/2013/12/06/why-i-hate-virtualenv-and-pip/

在许多情况下,它virtualenv都能发挥出色的作用,而且工作做得非常好!当然,它对我帮助很大,尤其是出于开发目的。在其他场景中,它要么不是一个完整的解决方案,甚至是一个糟糕的解决方案。

所以,现在我看到有一些不同的选择:

  1. 使用 virtualenv,但控制那些需要更改的内容。例如,在执行特定导入之前sys.path从包内进行修改。虽然有些人可能认为这“不干净”,但它确实是一种有效且可靠地控制目录搜索顺序的非常快速的方法。实际上被许多包和测试环境使用。这一点也不罕见。这种方法只需一分钟的工作就可以为您提供一个可行的解决方案。试一试!sys.path.insert(1, foo)
  2. 如果您认为您的案例中的 virtualenv 的行为与记录的不符或明显显示出错误行为,那么请将您的发现报告给项目。他们一定会感谢您简洁的反馈。
  3. 如果您认为 virtualenv 无法提供您的应用程序案例所需的隔离或控制级别,您可能需要考虑其他选项,例如 Docker 或 Vagrant,或全功能虚拟机。