首页 > 解决方案 > 为什么 IPython 的行为与 Python 的不同?

问题描述

在 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 的不同?

这与我之前的一个问题有关ipython 使用了哪个解释器?显示 IPython 和 Python 交互式 shell 都使用相同的 Python 实现,即 CPython。

对我来说,IPython只是一个外壳,应该只是将 python 代码的解释转发给与 Python 相同的底层解释器。因此,评估相同代码的结果应该是相同的(当然不是对象的地址,而是重用相同的事实)

注意:我可以很容易地想象出一些原因来解释为什么有时解释器能够为新对象重用相同的内存位置,有时不能,但我无法解释为什么这里的行为不同,因为两者都使用相同的实现。

这是重复的吗:对于询问这是否是 Python 的 id() 有多独特的重复?答案显然是否定的,我尽力解释上面的原因。也许不清楚?

标签: pythonipython

解决方案


这是一个非常有趣的观察,并没有多少人知道 IPython 在执行语句时使用两个线程。一个线程用于历史记录,另一个用于新的执行。每当您一个id接一个地调用时,第二个会在不同的线程中执行,这使得它具有不同的 id。

你可以玩弄你的发现:

在 IPython 中:

import threading
print(threading.activeCount())  # Should print "2"

# The statetement below should be printing alternating id numbers
# Such as "1 2 1 2" or smthng like that
print(id([])); print(id([])); print(id([])); print(id([]));

但是,普通的旧 python shell 使用单个线程,这意味着相同对象的 id 将始终相同。

在 Python 外壳中

import threading
print(threading.activeCount())  # Should print "1"

# The statetement below should be printing the same values
# Such as "1 1 1 1" or smthng like that
print(id([])); print(id([])); print(id([])); print(id([]));

更多信息:


推荐阅读