5

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

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)以查看 2 个可执行文件的配置信息是否有任何差异,但输出为空意味着它们相同。

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

笔记:

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

4

2 回答 2

4

与 C 扩展的二进制兼容性

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

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

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

于 2020-10-25T18:36:15.600 回答
1

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

这是执行此硬链接的 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
于 2020-08-03T04:29:11.227 回答