我知道有人解释了为什么当我在 Python 2.7 中创建相等的 unicode 字符串时,它们指向的内存位置与“普通”字符串不同
>>> a1 = 'a'
>>> a2 = 'a'
>>> a1 is a2
True
好的,这是我的预期,但是
>>> ua1 = u'a'
>>> ua2 = u'a'
>>> ua1 is ua2
False
为什么?如何?
我知道有人解释了为什么当我在 Python 2.7 中创建相等的 unicode 字符串时,它们指向的内存位置与“普通”字符串不同
>>> a1 = 'a'
>>> a2 = 'a'
>>> a1 is a2
True
好的,这是我的预期,但是
>>> ua1 = u'a'
>>> ua2 = u'a'
>>> ua1 is ua2
False
为什么?如何?
我认为常规字符串是实习的,但 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
不保证普通字符串会被保留。有时他们是,有时他们不是。这些规则很复杂,特定于版本,并且故意没有记录在案。
你可以依赖这样一个事实,即 Python 会尝试在一个好主意时尝试实习小型、常用的对象。而且,如果您编写任何依赖于任何一个a1 is a2
或相反的代码,它会在最不方便的时候中断。
如果您想要更多,则必须查看您感兴趣的任何实现的任何版本的源代码。对于 CPython,详细信息主要在stringobject.c
2.6和2.7以及3.3内部。unicodeobject.c
后一个文件当然也存在于 2.x 中(它仍然定义unicode
类型,这与str
3.x 中的类型不同)。您可以从2.7的源代码中看到,即使您无法调用它们,也有一些对实习字符串的支持。乍一看,2.7 似乎可以处理实习字符串,但永远不会创建它们。unicode
intern
unicode
同时,3.3 让事情变得更加有趣,因为一个str
对象可以指向 UTF-8、UTF-16 或 UTF-32 存储,它们可能会被实习,但使用旧式 Unicode API 的代码可能仍然会以新副本。因此,即使a1 is a2
,如果您尝试获取它们的字符,它们也可能具有不同的缓冲区。
python什么时候选择实习字符串对细节有更多的了解。但同样,来源才是最重要的。