Python字符串,末尾有空格和无空格,且不可变

Python字符串,末尾有空格和无空格,且不可变,python,string,immutability,cpython,python-internals,Python,String,Immutability,Cpython,Python Internals,我了解到在一些不可变类中,\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu 但为什么以下两个片段在行为上有所不同 末尾有一个空格: >>> a = 'string ' >>> b = 'string ' >>> a is b False 没有空格: >>>

我了解到在一些不可变类中,
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

但为什么以下两个片段在行为上有所不同

末尾有一个空格:

>>> a = 'string '
>>> b = 'string '
>>> a is b
False
没有空格:

>>> c = 'string'
>>> d = 'string'
>>> c is d
True

为什么空格会带来差异?

这是CPython实现如何选择缓存字符串文本的一个怪癖。具有相同内容的字符串文字可以引用相同的字符串对象,但它们不必引用<当
'string'
不是因为
'string'
只包含Python标识符中允许的字符时,code>'string'
会自动插入。我不知道为什么这是他们选择的标准,但事实确实如此。在不同的Python版本或实现中,行为可能不同

从CPython 2.7源代码第28行:

内部字符串(ob_sstate)尝试确保只有一个字符串 存在具有给定值的对象,因此相等性测试可以是一个指针 比较。这通常仅限于“看起来像”的字符串 Python标识符,尽管可以使用intern()内置 任何字符串的实习

您可以在中看到执行此操作的代码:


另外,请注意,实习是一个独立于Python字节码编译器合并字符串文本的过程。如果让编译器一起编译
a
b
赋值,例如将它们放在模块中或
如果为True:
,您会发现
a
b
将是相同的字符串。

此行为不一致,正如其他人提到的,这取决于正在执行的Python的变体。有关更深入的讨论,请参阅

如果要确保使用相同的对象,可以通过适当命名的
intern
,强制字符串的插入:

实习医生(……) 实习生(字符串)->字符串

``Intern'' the given string.  This enters the string in the (global)
table of interned strings whose purpose is to speed up dictionary lookups.
Return the string itself or the previously interned string object with the
same value.

注意在Python3中,您必须从sys import intern显式导入intern

对不起。不可复制:)您是在python interactive shell或scrip.py中执行的,在script.py中它返回相同的结果,所以我认为在编译代码时发生了一些事情。因为在iTreactive shell中,每一行都是在我们按enter键时编译的;b='st';a是b给出
True
关键字:may<代码>\uuuuu new\uuuuu可以返回对具有相同值的现有对象的缓存引用。它不能保证这样做。(我确实在CPython 3.2.3 64位上重现了这种行为。)并使它们在多行函数中仍然打印
True
我记得在某个地方读到过这方面的内容。你有一个链接准备好了吗?是的,我想看看一些实现细节,让我清楚地理解。不幸的是,我没有链接。我最接近的是我不认识的人和不信任的人之间的联系。@yopy:我找到了一个源代码链接,但不是处理该工作的源代码的实际部分。@user2357112,这正是我要找的。感谢感谢您提供的信息,但我一直在寻找其行为不同的原因。有关更多信息,请参阅。在Python 3中,
intern
现在位于
sys
模块中。
``Intern'' the given string.  This enters the string in the (global)
table of interned strings whose purpose is to speed up dictionary lookups.
Return the string itself or the previously interned string object with the
same value.
>>> a = 'string '
>>> b = 'string '
>>> id(a) == id(b)
False
>>> a = intern('string ')
>>> b = intern('string ')
>>> id(a) == id(b)
True