我有两台运行 Ubuntu 14.04 服务器的计算机(我们称它们为 A 和 B)。 B 最初是 10.04,但已两次升级到 12.04 和 14.04。不明白为什么两台电脑的python路径不一样。
下面两条路径可以看到,pip安装路径/usr/local/lib/python2.7/dist-packages
在apt python之前 Ubuntu A 上的包路径 /usr/lib/python2.7/dist-packages
,但它在 Ubuntu B 上位于之后。
如果通过 apt 和 pip 安装 python 包,这会导致几个问题。如下图所示,如果同时安装了python-six
apt包和six
pip包,可能是两个不同的库版本。
包系统的安装并不总是我的选择,但可能是安装的其他包的一些依赖项。
这个问题可能可以用 virtualenv 来解决,但是由于我不会详细说明的原因,我不能在这里使用 virtualenv,并且必须在系统范围内安装 pip 包。
Ubuntu A
>>> import sys, six
>>> sys.path
['',
'/usr/local/bin',
'/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',
'/usr/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages/PILcompat',
'/usr/local/lib/python2.7/dist-packages/IPython/extensions']
>>> six
<module 'six' from '/usr/local/lib/python2.7/dist-packages/six.pyc'>
Ubuntu B
>>> import sys, six
>>> sys.path
['',
'/usr/local/bin',
'/usr/lib/python2.7/dist-packages',
'/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',
'/usr/lib/python2.7/dist-packages/PILcompat',
'/usr/local/lib/python2.7/dist-packages/IPython/extensions']
>>> six
>>> <module 'six' from '/usr/lib/python2.7/dist-packages/six.pyc'>
对于两台机器,$PATH
是相同的,$PYTHONPATH
是空的。
为什么这些 PYTHONPATH 不同?
如何修复“Ubuntu B”中的 pythonpath 顺序以便它加载 pip 在系统包之前,以系统范围的方式包?是否有我应该重新安装或重新配置的 apt 包,以便 PYTHONPATH 会优先处理 pip 包吗?
最佳答案
由于我们无法探索您的系统,我试图通过说明 sys.path
是如何初始化的来分析您的第一个问题。可用的引用资料是 where-does-sys-path-starts和 pyco-reverse-engineering (python2.6).
sys.path
来自以下变量(按顺序):
$PYTHONPATH
(最高优先级)sys.prefix
-ed stdlibsys.exec_prefix
-ed stdlib站点包
*.pth
在站点包中(最低优先级)
现在让我们描述每个变量:
$PYTHONPATH
,这只是一个系统环境变量。- & 3.
sys.prefix
和sys.exec_prefix
在执行任何python 脚本之前确定。它实际上编码在源代码中 Module/getpath.c .
逻辑是这样的:
IF $PYTHONHOME IS set:
RETURN sys.prefix AND sys.exec_prefix as $PYTHONHOME
ELSE:
current_dir = directory of python executable;
DO:
current_dir = parent(current_dir)
IF FILE 'lib/pythonX.Y/os.py' EXSITS:
sys.prefix = current_dir
IF FILE 'lib/pythonX.Y/lib-dynload' EXSITS:
sys.exec_prefix = current_dir
IF current_dir IS '/':
BREAK
WHILE(TRUE)
IF sys.prefix IS NOT SET:
sys.prefix = BUILD_PREFIX
IF sys.exec_prefix IS NOT SET:
sys.exec_prefix = BUILD_PREFIX
& 5.
site-packages
和*.pth
是通过导入site.py
添加的。在此模块中,您将找到文档:这会将特定于站点的路径附加到模块搜索路径。上 Unix(包括 Mac OSX),它以 sys.prefix 和 sys.exec_prefix(如果不同)并追加 lib/python/site-packages 以及 lib/site-python。 …………
对于 Debian 和衍生产品,这个 sys.path 增加了目录 对于在发行版中分发的包。本地插件去 进入/usr/local/lib/python/dist-packages,Debian 插件 安装到/usr/{lib,share}/python/dist-packages。 /usr/lib/python/site-packages 未使用。
路径配置文件是一个名称具有以下形式的文件 .pth;它的内容是附加目录(每行一个) 要添加到 sys.path。 ……
以及重要功能getsitepackages
的代码片段:
sitepackages.append(os.path.join(prefix, "local/lib",
"python" + sys.version[:3],
"dist-packages"))
sitepackages.append(os.path.join(prefix, "lib",
"python" + sys.version[:3],
"dist-packages"))
现在我试着弄清楚这个奇怪的问题可能来自哪里:
$PYTHONPATH
,不可能,因为A和B都是空的sys.prefix
和sys.exec_prefix
,也许,请检查它们以及$PYTHONHOME
site.py
,也许,检查文件。
B 的 sys.path
输出很奇怪,dist-package
(site-package
) 在 sys 之前。 exec_prefix
(lib-dynload
)。请尝试调查机器 B 的 sys.path
初始化的每个步骤,您可能会发现一些东西。
非常抱歉,我无法复制您的问题。顺便说一句,关于你的问题标题,我认为 SYS.PATH
比 PYTHONPATH
好,这让我乍一看误认为是 $PYTHONPATH
.
关于Ubuntu 14.04 上的 PYTHONPATH 命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39748267/