python - 为什么字符串比较和标识在 pdb 和 python 控制台中的行为不同

标签 python pdb

我在 python 控制台和 pdb 中运行相同的 python 代码片段,但得到如下不同的结果:

数据库:

>>> import pdb
>>> pdb.set_trace()
(Pdb) print u'你好' == u'\u4f60\u597d'
False
(Pdb) print u'你好' is u'\u4f60\u597d'
False
(Pdb) print id(u'你好'), id(u'\u4f60\u597d')
4431713024 4431713120
(Pdb) id(u'你好')
4431713024
(Pdb) id(u'\u4f60\u597d')
4431713024

python 控制台:

>>> print u'你好' == u'\u4f60\u597d'
True
>>> print u'你好' is u'\u4f60\u597d'
True
>>> print id(u'你好'), id(u'\u4f60\u597d')
4376711984 4376711984
>>> id(u'你好')
4376711984
>>> id(u'\u4f60\u597d')
4376711984

我的python版本是2.7.13

所以我的问题:

1.为什么运算符(如“==”和“is”)在两个控制台中的表现不同。

2.在pdb中,id(u'\u4f60\u597d')等于4431713120在

print id(u'你好'), id(u'\u4f60\u597d')

但是 4431713024 在

id(u'\u4f60\u597d')

3.为什么在python3中不会出现这种情况

最佳答案

让我们从 is 检查开始,因为这更容易回答。

请注意,当您在两个单独的行中检查 id 时,解释器和调试器都会为两个字符串显示相同的 id。这是因为第一个字符串是在某个地址初始化的,你打印它的id。然后您创建一个新字符串并使用相同的变量名,因此不再有指向第一个字符串的引用。这意味着第一个字符串被垃圾收集并释放其内存。新创建的字符串占用第一个空闲内存空间,恰好是刚刚空闲的那个。因此,它与第一个字符串拥有(当它还活着时)具有相同的id

当检查同一行中的 id 时,情况有所不同,因为两个字符串同时存在。这里解释器和调试器的行为不同。解释器实习字符串,因此它们是相同的对象,因此具有相同的 id,而调试器则没有。 (引用 Python string interning ,由 @DeepSpace in the comments 推荐,了解更多关于实习的信息)。

我认为根本原因实际上可以在第一个测试中看到,u'你好' == u'\u4f60\u597d'。这两个字符串在解释器和调试器中的表示方式不同,因此它无法保留它们(因为调试器认为它们是两个不同的字符串)。

调试器为两个字符串分配不同的代码点:

(Pdb) map(ord, u'你好')
[228, 189, 160, 229, 165, 189]
(Pdb) map(ord, u'\u4f60\u597d')
[20320, 22909]

虽然解释器没有:

>>> map(ord, u'你好')
[20320, 22909]
>>> map(ord, u'\u4f60\u597d')
[20320, 22909]

至于为什么不,这个问题需要其他人来回答。

关于python - 为什么字符串比较和标识在 pdb 和 python 控制台中的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49008781/

相关文章:

Python Pdb 给我一个回溯并且无法运行

python - pdb的post_mortem方法怎么用?

python - 如何在 python 脚本中使用 cpulimit

python - GET curl 调用不返回 JSON 对象

python - 为什么我的 Flask 应用程序中的图像无法正常显示?

python - Emacs python 模式 : Keyboard shortcuts for pdb step-by-step debugging

python - pdb:如何显示当前行,而不是在上一个列表之后继续?

python - spotipy授权代码流程

python - 在Python中使用重复的函数调用来循环某些东西(即列表)是否合适?

r - 使用 `browser()` 时如何从命令行使用 R 的 `Rscript` 函数