Python 中 sys.executable 和 sys.version 不匹配 [英] Mismatch between sys.executable and sys.version in Python

查看:74
本文介绍了Python 中 sys.executable 和 sys.version 不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

安装了两个 Python 解释器:

There are two Python interpreters installed:

[user@localhost ~]$ /usr/bin/python -V && /usr/local/bin/python -V
Python 2.4.3
Python 2.7.6

Sudo 会为它运行的每个命令更改 PATH,如下所示:

Sudo changes PATH for every command it runs as follows:

[user@localhost ~]$ env | grep PATH && sudo env | grep PATH
PATH=/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/home/user/bin
PATH=/usr/bin:/bin

我运行一个测试脚本:

[user@localhost ~]$ cat what_python.py
#!/usr/bin/env python

import sys
print sys.executable
print sys.version
[user@localhost ~]$ sudo python what_python.py
/usr/bin/python
2.7.6 (default, Feb 27 2014, 17:05:07) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)]

并在 sys.executable 中获取 Python 2.4.3 的路径以及在 sys.version 中报告的 2.7.6 版本.显然 sys.executablesys.version 不匹配.考虑到 sudo 如何修改 PATH,我可以理解 sys.executable 的值.但是,为什么 sys.version 报告版本 2.7.6 而不是版本 2.4.3,这将匹配 sys.executable 报告的 usr/bin/python 路径?

and get path to Python 2.4.3 in sys.executable and version 2.7.6 reported in sys.version. Clearly sys.executable and sys.version do not match. Taking into account how sudo modifies PATH I can understand the value of sys.executable. However, why does sys.version report version 2.7.6 and not version 2.4.3, which would match usr/bin/python path reported by sys.executable?

这是我的问题 Sudo 更改 PATH,但执行相同的二进制文件

推荐答案

两者都是@Graeme

Both @Graeme

python 可能无法检索 this 的事实表明它正在做自己的 PATH 搜索 (...)

The fact that python may be unable to retrieve this suggests that it is doing its own PATH search (…)

和@twalberg

(...) 看起来 sys.executable 搜索当前 PATH 而不是解析 argv[0] (或者可能是因为 argv[0] 在这案例...), (...)

(…) it looks like sys.executable searches the current PATH instead of resolving argv[0] (or maybe because argv[0] is simpy python in this case...), (…)

基本上是对的.我不愿意相信 Python 做了一些如此简单(愚蠢?)的事情,比如使用 PATH 来定位自己,但这是真的.

were basically right. I was reluctant to believe that Python does something so simple (silly?) as using PATH to locate itself but this is true.

Python 的 sys 模块在 Python/sysmodule.c 文件中实现.从 2.7.6 版开始,sys.executable 设置在 1422 像这样:

Python's sys module is implemented in Python/sysmodule.c file. As of version 2.7.6, sys.executable is set at line 1422 like this:

 SET_SYS_FROM_STRING("executable",
                     PyString_FromString(Py_GetProgramFullPath()));

Py_GetProgramFullPath() 函数在文件 Modules/getpath.c 中定义,从 701:

Py_GetProgramFullPath() function is defined in file Modules/getpath.c starting from line 701:

char *
Py_GetProgramFullPath(void)
{
    if (!module_search_path)
        calculate_path();
    return progpath;
}

函数calcuate_path()定义在同一个文件中,包含以下评论:

Function calcuate_path() is defined in the same file and contains the following comment:

/* If there is no slash in the argv0 path, then we have to
 * assume python is on the user's $PATH, since there's no
 * other way to find a directory to start the search from.  If
 * $PATH isn't exported, you lose.
 */

在我的例子中可以看出,当导出的 $PATH 上的第一个 Python 与正在运行的 Python 不同时,也会失败.

As can be seen in my case, one loses also when the first Python on exported $PATH is different than the Python being run.

更多关于计算解释器可执行文件位置的信息可以在 getpath.c 文件的 "nofollow noreferrer">顶部:

More information on the process of calculating placement of interpreter's executable can be found at the top of getpath.c file:

在完成任何搜索之前,可执行文件的位置是决定.如果 argv[0] 中有一个或多个斜杠,则使用它不变.否则,它必须是从 shell 的路径调用的,所以我们在 $PATH 中搜索命名的可执行文件并使用它.如果在 $PATH 上找不到可执行文件(或没有 $PATH 环境变量),使用原始的 argv[0] 字符串.

Before any searches are done, the location of the executable is determined. If argv[0] has one or more slashes in it, it is used unchanged. Otherwise, it must have been invoked from the shell's path, so we search $PATH for the named executable and use that. If the executable was not found on $PATH (or there was no $PATH environment variable), the original argv[0] string is used.

接下来,检查可执行位置以查看它是否是符号关联.如果是这样,则链接被追逐(正确解释亲戚路径名(如果找到),并使用链接目标的目录.

Next, the executable location is examined to see if it is a symbolic link. If so, the link is chased (correctly interpreting a relative pathname if one is found) and the directory of the link target is used.

让我们做几个测试来验证上述内容:

Let's make a couple of tests to verify the above:

如果 argv[0] 中有一个或多个斜线,则原样使用.

[user@localhost ~]$ sudo /usr/local/bin/python what_python.py
/usr/local/bin/python
2.7.6 (default, Feb 27 2014, 17:05:07) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)]

好的.

如果在 $PATH 上找不到可执行文件(或没有 $PATH 环境变量),则使用原始的 argv[0] 字符串.

[user@localhost ~]$ sudo PATH= python what_python.py
<empty line>
2.7.6 (default, Feb 27 2014, 17:05:07) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)]

错了.在这种情况下,来自 sys 模块的 documentation 的陈述为真 - 如果 Python无法检索到其可执行文件的真实路径,sys.executable 将为空字符串或无. .

Wrong. In this case statement from sys module's documentation is true – If Python is unable to retrieve the real path to its executable, sys.executable will be an empty string or None. .

让我们看看是否将 python 的二进制文件的位置添加回 PATH(在 sudo 删除它之后)修复问题:

Let's see if adding location of python's binary back to the PATH (after sudo had removed it) fixes the problem:

[user@localhost ~]$ sudo PATH=$PATH python what_python.py
/usr/local/bin/python
2.7.6 (default, Feb 27 2014, 17:05:07) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)]

确实如此.

相关:

  • Python 问题 7774 – sys.executable:如果修改了第零个命令参数,则位置错误.
  • Python 问题 10835 – sys.executable 默认和 altinstall
  • python-dev 邮件列表 线程 –对 sys.executable 进行更严格的定义
  • Stackoverflow 问题 - 如何在 C 中找到可执行文件的位置
  • Python issue 7774 – sys.executable: wrong location if zeroth command argument is modified.
  • Python issue 10835 – sys.executable default and altinstall
  • python-dev mailing list thread – towards a stricter definition of sys.executable
  • Stackoverflow question – how to find the location of the executable in C

这篇关于Python 中 sys.executable 和 sys.version 不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆