当前位置: 首页 > 面试题库 >

Python:解释器中的id()行为[重复]

徐翔
2023-03-14
问题内容

这个问题已经在这里有了答案

Python何时为相同的字符串分配新的内存? (5个答案)

7年前关闭。

我遇到了这种奇怪的行为,这种行为仅在交互式Python会话中发生,而在编写脚本并执行时却没有。

在Python中,字符串是不可变的数据类型,因此:

>>> s2='string'
>>> s1='string'
>>> s1 is s2
True

现在,奇怪的部分:

>>> s1='a string'
>>> s2='a string'
>>> s1 is s2
False

我已经看到,字符串中包含空格会导致此行为。如果将其放在脚本中并运行,则在两种情况下结果均为True。

有人对此有任何线索吗?谢谢。

编辑:

好的,上面的问题和答案给出了一些想法。现在这是另一个实验:

>>> s2='astringbstring'
>>> s1='astringbstring'
>>> s1 is s2
True

在这种情况下,字符串肯定比更长'a string',但仍具有相同的标识符。


问题答案:

非常感谢@eryksun的更正!

这是由于interningPython中的机制调用:

在“
interned”字符串表中输入string并返回被中断的字符串–它是字符串本身或副本。插入字符串对于提高字典查找的性能很有用–如果字典中的键被插入,并且查找键被插入,则键比较(散列后)可以通过指针比较而不是字符串比较来完成。通常,Python程序中使用的名称会被自动插入,并且用于保存模块,类或实例属性的字典具有插入键。

在版本2.3中进行了更改:内联字符串不是不朽的(就像它们曾经在Python
2.2及之前的版本中一样);您必须保留对intern()返回值的引用,以从中受益。

CPython 会自动实习 某些字符串(1个字母字符串,关键字,没有分配空格的字符串)以提高查找速度和比较速度:例如,'dog' is 'dog'将是指针比较而不是完整的字符串比较。但是,对所有(较长)字符串的自动实习需要更多的内存,这并不总是可行的,因此它们可能不会共享相同的标识,从而导致结果id()不同,例如:

# different id when not assigned
In [146]: id('dog')
Out[146]: 4380547672

In [147]: id('dog')
Out[147]: 4380547552

# if assigned, the strings will be interned (though depends on implementation)
In [148]: a = 'dog'

In [149]: b = 'dog'

In [150]: id(a)
Out[150]: 4380547352

In [151]: id(b)
Out[151]: 4380547352

In [152]: a is b
Out[152]: True

对于整数,至少在我的机器上,CPython会自动自动最多迭代256个:

In [18]: id(256)
Out[18]: 140511109257408

In [19]: id(256)
Out[19]: 140511109257408

In [20]: id(257)
Out[20]: 140511112156576

In [21]: id(257)
Out[21]: 140511110188504

由于@eryksun而进行的更新 :在这种情况下,该字符串'a string'没有被插入,因为CPython仅插入没有空格的字符串,而不是因为我立即假定的长度:例如ASCII字母,数字和下划线。

有关更多详细信息,您还可以在此处参考Alex
Martelli的答案



 类似资料:
  • 当我们编写Python代码时,我们得到的是一个包含Python代码的以.py为扩展名的文本文件。要运行代码,就需要Python解释器去执行.py文件。 由于整个Python语言从规范到解释器都是开源的,所以理论上,只要水平够高,任何人都可以编写Python解释器来执行Python代码(当然难度很大)。事实上,确实存在多种Python解释器。 CPython 当我们从Python官方网站下载并安装好

  • 当我们编写Python代码时,我们得到的是一个包含Python代码的以.py为扩展名的文本文件。要运行代码,就需要Python解释器去执行.py文件。 由于整个Python语言从规范到解释器都是开源的,所以理论上,只要水平够高,任何人都可以编写Python解释器来执行Python代码(当然难度很大)。事实上,确实存在多种Python解释器。 CPython 当我们从Python官方网站下载并安装好

  • 问了这个问题后,我很困惑,于是决定为一个C编译器程序构建类似的测试。这是我的代码: 使用选项在GCC下编译 测试代码被更改,这样错误值只能在运行时知道(而不能在编译时知道),这样GCC优化器就不能删除循环的代码。 我们应该期待CPU的加速吗?(正如GCC编译程序预测的那样)

  • 2. Python 解释器 2.1 调用解释器 在可用的机器上,Python解释器通常安装成/usr/local/bin/python;请将/usr/local/bin放在您的Unix shell搜索路径,以使得可以通过在shell中键入命令 python 来启动它。由于解释器放置的目录是一个安装选项,其它地方也是可能的;请与您本地的Python专家或系统管理员联系。(例如,/usr/local

  • 我已经设置了一个Python项目,指向运行在中的: 从启动应用程序将产生以下输出: 试图打开http://localhost:5000/ 导致页面未找到错误。 如果我使用Docker与Dockerfile运行应用程序: 上述Dockerfile构建PyCharm连接的容器,并在PyCharm中配置为: 使用命令

  • 问题内容: 我正在尝试从解释器中使用python命令执行文件。 编辑:我正在尝试使用该文件中的变量和设置,而不是调用一个单独的进程。 问题答案: 几种方法。 从外壳 从IDLE内部,按 F5 。 如果您是交互式输入,请尝试以下操作:( 仅适用于Python 2 !) 对于Python3 ,请使用: