具有特殊字符的相等字符串的不同存储位置[重复]

Posted

技术标签:

【中文标题】具有特殊字符的相等字符串的不同存储位置[重复]【英文标题】:Different storage position of equal strings with special characters [duplicate] 【发布时间】:2014-09-30 17:24:26 【问题描述】:

我是 python 新手,目前正在探索它的一些核心功能。

你能解释一下为什么下面的例子总是在字符串带有特殊字符的情况下返回 false:

>>> a="x"
>>> b="x"
>>> a is b
True
>>> a="xxx"
>>> b="xxx"
>>> a is b
True
>>> a="xü"
>>> b="xü"
>>> a is b
False
>>> a="ü"
>>> b="ü"
>>> a is b
True
>>> #strange: with one special character it works as expected

我知道每个赋值中带有特殊字符的字符串的存储位置是不同的,我已经用 id() 函数检查过了,但是为什么 python 以这种不一致的方式处理字符串?

【问题讨论】:

【参考方案1】:

Python(至少是参考实现)有一个用于小整数和字符串的缓存。我猜 ASCII 范围之外的 unicode 字符串大于缓存阈值(内部 unicode 使用 16 位或 32 位宽字符存储,UCS-2 or UCS-4),因此它们不会被缓存。

[编辑]

找到更完整的答案:About the changing id of a Python immutable string

还有:http://www.laurentluce.com/posts/python-string-objects-implementation/

【讨论】:

我将编辑我的问题,为什么 a="xxxxxx" b="xxxxxx" a is b 仍然正确? 这在某处有记录吗? 是的,它已记录在案,我正在寻找参考以检查所涉及的尺寸。【参考方案2】:

您不是在测试字符串之间的相等性,而是在测试通过指针解析的对象之间的相等性。所以你的代码:

>>> a="x"
>>> b="x"
>>> a is b
True

不是问“a 和 b 是同一个字符吗?”,而是问“a 和 b 是同一个对象吗?”。由于有一个小对象缓存(对于小整数和一字节字符串,如前所述),答案是“是的,两个变量都引用内存中的同一个对象,即 x 字符小对象”。

当您使用不符合缓存条件的对象时,例如:

>>> a="xü"
>>> b="xü"
>>> a is b
False

现在发生的事情是 a 和 b 现在引用内存中的不同对象,因此 is 运算符解析为 false(a 和 b 不指向同一个对象!)。

如果这个想法是比较字符串,你应该使用 == 运算符而不是 is。

【讨论】:

>>> a="xxx" >>> b="xxx" >>> a is b True 这个呢? 在我的测试中,长度不超过 20 个字符的 ASCII 字符的字符串使用 is.那将是缓存工作以避免为可缓存的字符串创建新对象。 YMMV,我使用的是 Windows 8 64 位 Python 2.7.6 64 位。 请注意,如果您的测试在 REPL 上运行或作为脚本运行,GC 可能会以不同的方式运行。

以上是关于具有特殊字符的相等字符串的不同存储位置[重复]的主要内容,如果未能解决你的问题,请参考以下文章

遍历包含文件名中具有特殊字符的文件的目录会导致错误[重复]

在字符串中搜索具有特殊字符的子字符串[重复]

如何防止用户在文本框中输入特殊字符[重复]

如何在postgresql中存储符号或特殊字符[重复]

2022-10-17:特殊的二进制序列是具有以下两个性质的二进制序列: 0 的数量与 1 的数量相等。 二进制序列的每一个前缀码中 1 的数量要大于等于 0 的数量。 给定一个特殊的二进制序列 S,以

正则表达式,用于验证不同格式的字符串,用于特殊时间转换[重复]