【问题标题】:"WHY" 2 different executables of python of same version?“为什么”相同版本的 2 个不同的 python 可执行文件?
【发布时间】:2020-08-02 15:34:37
【问题描述】:

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

python3.7          python3.7-config   python3.7m         python3.7m-config

我查找了python3.7m 并找到了答案 - https://stackoverflow.com/a/16677339/6849682

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

>>> import sysconfig
>>> sysconfig.get_config_var('EXT_SUFFIX')

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

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

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

注意:

我不是在说python3.7/3.7m-config

【问题讨论】:

  • python3.7-config 不是同一个可执行文件。根据手册页“python-config 帮助编译和链接嵌入 Python 解释器的程序,或可以动态(在运行时)加载到解释器中的扩展模块”。至于python3.7python3.7m,我不知道“-m”版本,但在Linux 中,一个应用程序到另一个应用程序的符号链接是很常见的。例如,更改是在您的系统中还有一个python3 命令指向python3.7 可执行文件。
  • @wovano 我不是在问python3.7-config
  • 您在前几行中提到了它。如果它与您的问题无关,也许您应该删除它。
  • 我不知道答案,但 PEP 似乎有一个提示:“默认情况下,在 Python 3.2 中,configure 启用 --with-pymalloc,因此共享库文件名将显示为foo.cpython-32m.so"。所以也许python3m 是为了兼容性而保留的?

标签: python python-3.x python-internals pythoninterpreter


【解决方案1】:

与 C 扩展的二进制兼容性

为了使 C 扩展在解释器构建中兼容,一些构建时标志需要相同。其中一个标志是是否启用了pymalloc(一个旨在为 Python 特定用例提供更快速度的内存分配库)。 libpython 的版本有一个m 后缀,表明这个标志在构建时就存在,而实际上它确实存在。

如果使用 pymalloc 支持构建 C 扩展,则使用标准 C 库的 malloc() 的解释器不能使用它,反之亦然。因此,对于将 C 扩展作为使用 pymalloc 构建的预构建二进制文件的人来说,能够启动一个已知为 pymalloc 启用的 Python 解释器会很有用。

如果 Linux 发行版选择提供支持 pymalloc 的解释器,那么在 python3.7python3.7m 名称下只提供一个二进制文件是有意义的。 (这让需要非 pymalloc 解释器的人有点不走运,但在 Linux 上构建工具并不像在 Windows 上那样难以获得,因此 ABI 兼容性并不那么重要)。

【讨论】:

    【解决方案2】:

    python3.7python3.7m 是同一个程序,只是有两个不同的名称。这两个文件是hard-linked,这意味着它们指向磁盘上的同一个文件(即它们具有相同的inode)。

    这是执行此硬链接的the line in the cpython 3.7 Makefile

    (cd $(DESTDIR)$(BINDIR); $(LN) python$(LDVERSION)$(EXE) python$(VERSION)$(EXE));
    

    $(LDVERSION) 将是 3.7m$(VERSION) 将是 3.7。这是 Makefile 中唯一执行硬链接的地方。


    下面使用python3.7 Docker镜像来演示python3.7python3.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
    

    【讨论】:

    • 谢谢,如果您阅读我的问题,它会询问WHY 2 个不同的可执行文件
    • @bigbounty,答案已经涵盖了。它们不是两个不同的可执行文件。硬链接在一起意味着它们是同一个可执行文件的两个名称,但它实际上只存储在您的硬盘上一次。
    • @bigbounty, ...在这种情况下,这是有道理的,因为m 后缀意味着使用 pymalloc 编译,因此意味着解释器可以与为基于 pymalloc 的解释器编译的 C 扩展一起使用(这在大多数用户没有编译器并且无法自己编译扩展的 Windows 世界中是一件大事,因此他们需要安装为他们实际拥有的解释器类型构建的版本)。如果您的主要 Python 解释器与启用 pymalloc 的 Python 解释器相同,则将两个名称都指向同一个位置是有意义的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-24
    相关资源
    最近更新 更多