5

我知道有人解释了为什么当我在 Python 2.7 中创建相等的 unicode 字符串时,它们指向的内存位置与“普通”字符串不同

>>> a1 = 'a'
>>> a2 = 'a'
>>> a1 is a2
True

好的,这是我的预期,但是

>>> ua1 = u'a'
>>> ua2 = u'a'
>>> ua1 is ua2
False

为什么?如何?

4

2 回答 2

3

我认为常规字符串是实习的,但 unicode 字符串不是。这个简单的测试似乎支持我的理论(Python 2.6.6):

>>> intern("string")
'string'
>>> intern(u"unicode string")

Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    intern(u"unicode string")
TypeError: intern() argument 1 must be string, not unicode
于 2013-03-13T18:49:21.960 回答
2

不保证普通字符串会被保留。有时他们是,有时他们不是。这些规则很复杂,特定于版本,并且故意没有记录在案。

你可以依赖这样一个事实,即 Python 会尝试在一个好主意时尝试实习小型、常用的对象。而且,如果您编写任何依赖于任何一个a1 is a2或相反的代码,它会在最不方便的时候中断。

如果您想要更多,则必须查看您感兴趣的任何实现的任何版本的源代码。对于 CPython,详细信息主要在stringobject.c2.62.7以及3.3内部unicodeobject.c

后一个文件当然也存在于 2.x 中(它仍然定义unicode类型,这与str3.x 中的类型不同)。您可以从2.7的源代码中看到,即使您无法调用它们,也一些对实习字符串的支持。乍一看,2.7 似乎可以处理实习字符串,但永远不会创建它们。unicodeinternunicode

同时,3.3 让事情变得更加有趣,因为一个str对象可以指向 UTF-8、UTF-16 或 UTF-32 存储,它们可能会被实习,但使用旧式 Unicode API 的代码可能仍然会以新副本。因此,即使a1 is a2,如果您尝试获取它们的字符,它们也可能具有不同的缓冲区。

python什么时候选择实习字符串对细节有更多的了解。但同样,来源才是最重要的。

于 2013-03-13T19:00:58.227 回答