排序sys.path:首先是virtualenv,然后是/usr [英] Sorting sys.path: first virtualenv, then /usr
问题描述
为什么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
进行排序?
我为什么使用系统站点软件包
似乎没有直接的方法来使virtualenv中的全局站点程序包中的单个库可用.看到这个问题: 在virtualenv中使全局站点包中的某些模块可用
有些软件包如python-gtk很难安装在virtualenv中.
讨论后进行
我希望我的virtualenv(/usr ...)之外的所有路径都位于 virtualenv的路径. [...]它需要排序."
然后,只需在第一次导入之前对sys.path
进行排序.给定与您的virtalenv位置相对应的特定路径prefix
,此方法可能就足够了:
sys.path = sorted(sys.path, key=lambda x: x.startswith(prefix), reverse=True)
sorted()
的排序行为是稳定的:保留具有相同排序键的项目的原始顺序.在这里,仅使用两个排序键:True
和False
.您需要想出一种可靠的方法来设置prefix
(您可能想对其进行硬编码,或者根据当前的工作目录来确定它,我相信您会找到一种方法).
原始答案(通常仍然有效):
您不想过多地阐述您的需求和应用场景,因此我提供了一个更笼统的答案:您可能需要考虑一下方法,也许不希望virtualenv
能够完全解决您的问题. >
在某些情况下, Why does I create the virtualenv with The I want all paths outside my virtualenv ( Otherwise crazy things happen: I install a package with pip. Pip tells me that the new version is installed ( I can't use Is there a way to sort Why I use system-site-packages There seems to be no straight forward way to make single libraries from the global site-packages available in the virtualenv. See this question:
make some modules from global site-packages available in virtualenv There are packages like python-gtk which are very hard to install in a virtualenv. Edit, after discussion: "I want all paths outside my virtualenv (/usr...) to be below the
paths of the virtualenv. [...] It needs to be sorted." Then, just sort your Original answer (still valid, in general): You did not want to elaborate on your requirements and application scenario too much, so I provide a more general answer: you may need to overthink your approach, and maybe not expect In certain situations, In many scenarios So, there are a few different options now that I see:
这篇关于排序sys.path:首先是virtualenv,然后是/usr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!virtualenv
并不是完美的解决方案. 是一种妥协,本文对这一妥协的一面进行了详尽描述:sys.path.insert(1, foo)实际上由许多软件包和测试环境使用.一点也不罕见.仅需一分钟的工作时间,此方法即可为您提供可行的解决方案.试试看!
sys.path
contain /usr/...
before directories from my virtualenv?--system-site-packages
sys.path
looks like this at the moment:/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
/usr...
) to be below the paths of the virtualenv.pip freeze | grep -i ...
) but the import does use the one from /usr/lib/python2.7/site-packages
--no-site-packages
in my context.sys.path
?
sys.path
before the first import happens. Given a certain path prefix
corresponding to the location of your virtalenv, this approach likely is sufficient:sys.path = sorted(sys.path, key=lambda x: x.startswith(prefix), reverse=True)
sorted()
's sorting behavior is stable: the original order is preserved for items with same sort key. Here, only two sort keys are used: True
and False
. You need to come up with a reliable way to set your prefix
(You might want to hard-code it, or determine it based on the current working directory, I am sure you find a way).virtualenv
to entirely solve your problem.virtualenv
is just not the perfect solution. It is a compromise, and one side of this compromise is exhaustively described in this article: https://pythonrants.wordpress.com/2013/12/06/why-i-hate-virtualenv-and-pip/virtualenv
serves a splendid purpose and does its job very fine! It helped me a lot, for sure, especially for development purposes. In other scenarios, it is either not a complete solution or even a bad solution.
sys.path
from within your package before doing a certain import. While some might consider this "not clean", it for sure is a very quick way to efficiently and reliably control directory search order. sys.path.insert(1, foo)
is actually used by many packages and test environments. It not uncommon at all. This approach may provide you with a working solution after just one minute of work. Give it a try!