“为什么”同一版本的 2 个不同的 python 可执行文件?

big*_*nty 5 python python-3.x python-internals pythoninterpreter

当我按下tab命令时python3.7,我得到以下信息

python3.7          python3.7-config   python3.7m         python3.7m-config
Run Code Online (Sandbox Code Playgroud)

我查了一下内容python3.7m并找到了答案 - /sf/answers/1167413761/

接下来我进入每个实现的python终端并输入以下代码

>>> import sysconfig
>>> sysconfig.get_config_var('EXT_SUFFIX')
Run Code Online (Sandbox Code Playgroud)

我在两个 python 实现中得到相同的输出,即.cpython-37m-darwin.so

我还尝试了该命令diff <(python3.7 -m sysconfig) <(python3.7m -m sysconfig)来查看两个可执行文件的配置信息是否有任何差异,但输出为空意味着它们是相同的。

如果所有可执行文件和配置变量都相同,那么为什么要创建两个不同的 python 实现呢?

笔记:

我不是在谈论python3.7/3.7m-config这里。

Jak*_*kub 2

python3.7python3.7m是同一个程序,只是有两个不同的名称。这两个文件是硬链接的,这意味着它们指向磁盘上的同一个文件(即它们具有相同的索引节点)。

这是cpython 3.7 中Makefile执行此硬链接的行。

(cd $(DESTDIR)$(BINDIR); $(LN) python$(LDVERSION)$(EXE) python$(VERSION)$(EXE));
Run Code Online (Sandbox Code Playgroud)

$(LDVERSION)将会是3.7m,并且$(VERSION)将会是3.7。这是 Makefile 中唯一执行硬链接的位置。


下面使用 python3.7 Docker 镜像来演示,python3.7并且python3.7具有相同的 inode。

$ docker run --rm -it python:3.7-alpine ash
/ # ls -i $(which python3.7)
 927902 /usr/local/bin/python3.7
/ # ls -i $(which python3.7m)
 927902 /usr/local/bin/python3.7m
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,如果您阅读我的问题,它会询问“为什么”2个不同的可执行文件 (4认同)
  • @bigbounty,...在这种情况下,这是有道理的,因为“m”后缀意味着使用 pymalloc 进行编译,因此意味着解释器可以与为基于 pymalloc 的解释器编译的 C 扩展一起使用(这在 Windows 中是一件大事)大多数用户没有编译器并且无法自己编译扩展,因此他们需要安装为他们实际拥有的解释器类型构建的版本)。如果您的主 Python 解释器与启用 pymalloc 的 Python 解释器相同,则让两个名称指向同一位置是有意义的。 (3认同)
  • @bigbounty,答案已经涵盖了它。它们**不是**两个不同的可执行文件。硬链接在一起意味着它们是同一可执行文件的两个名称,但它实际上只在硬盘上存储一次。 (2认同)