【问题标题】: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 以这种不一致的方式处理字符串?

【问题讨论】:

    标签: python python-2.7


    【解决方案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 可能会以不同的方式运行。
    猜你喜欢
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 2020-11-04
    • 2020-03-20
    • 2011-04-11
    • 2012-09-07
    • 2014-03-18
    • 2019-11-07
    相关资源
    最近更新 更多