【发布时间】:2020-11-03 20:01:16
【问题描述】:
在 Python 3.8.5 shell 中,我有:
>>> id([])
140370451791744
>>> id([])
140370451791744
>>> id([])
在运行 Python 3.8.5 的 IPython 7.18.1 中,我有:
In [1]: id([])
Out[1]: 139870334633536
In [2]: id([])
Out[2]: 139870334633152
这让我想到了以下问题:为什么 IPython 的行为与 python 的不同?
这与我之前提出的Which interpreter is used by ipython? 的问题有关,表明 IPython 和 Python 交互式 shell 使用相同的 Python 实现,即 CPython。
对我来说,IPython 只是一个外壳程序,应该只是将 Python 代码的解释转发给与 Python 相同的底层解释器。因此,对相同代码求值的结果应该是相同的(当然不是对象的地址,而是重用相同的事实)
注意:我可以很容易地想出一些原因来解释为什么有时解释器能够为新对象重用相同的内存位置,而有时却不能,但我无法解释为什么这里的行为会有所不同,因为两者都使用相同的实现。
这是重复的吗:对于询问这是否与How unique is Python's id()? 重复的人,答案显然是否定的,我已尽力解释上述原因。也许不清楚?
【问题讨论】:
-
这能回答你的问题吗? How unique is Python's id()?
-
两个不同的对象,具有不相交的生命周期,是否具有相同的 id 是对于所有目的完全无关。绝对没有保证会发生的情况,绝对没有保证不会发生的情况。在这种情况下,IPython 恰好比普通的 CPython 执行更多的 Python 代码(例如,生成那些花哨的 In/Out 提示),所以只能说这是两种不同的情况。
-
是的,IPython 是用 Python 编写的。 纯 Python,甚至,或者至少是我刚刚检查的版本。
-
downvoting 最好在心理学论坛中解释。但用我自己的话来说,一般来说,人们不喜欢提出不便的问题的人。
-
ipython维护了较长的输出历史,这可能会影响内存使用和重用的细节。生成具有不同 id 的空列表的最可靠方法是将它们收集在一个列表中,例如。alist = [[],[],[]]。现在看看[id(i) for i in alist]。一般来说,查看id()并没有多大价值。