Python 比较unicode对象和字符串对象时的奇怪行为

Python 比较unicode对象和字符串对象时的奇怪行为,python,python-2.7,unicode,Python,Python 2.7,Unicode,在python中比较两个字符串时,它工作正常,当比较string对象和unicode对象时,它会按预期失败,但是当比较string对象和转换的unicode(unicode-->str)对象时,它会失败 演示: 按预期工作: 差不多是的: 不应为: 当两个类型都属于同一类时,为什么第三个示例不能按预期工作 >>> type('s') <type 'str'> >>> type(str(u's')) <type 'str'> >

在python中比较两个字符串时,它工作正常,当比较
string
对象和
unicode
对象时,它会按预期失败,但是当比较
string
对象和转换的unicode
(unicode-->str)
对象时,它会失败

演示: 按预期工作:


差不多是的:


不应为:


当两个类型都属于同一类时,为什么第三个示例不能按预期工作

>>> type('s')
<type 'str'>

>>> type(str(u's'))
<type 'str'>
>>类型('s')
>>>类型(str(u's'))

不要使用
is
为此,请使用
=
。您正在比较对象是否具有相同的标识,而不是它们是否相等。当然,如果它们是相同的对象,它们将相等(
==
),但是如果它们相等,它们不一定是相同的对象

第一个有效的事实是CPython的一个实现细节。小字符串,因为它们是不可变的,可以被解释器保留。每次在源代码中放入字符串
“s”
,Cpython都会重用相同的对象。但是,显然
str(“s”)
返回一个具有相同值的新字符串。这并不奇怪



您可能会问自己,“为什么要插入字符串
。这是一个合理的问题。毕竟,这是一个短字符串——在源代码中浮动多个副本会占用多少内存?答案(我想)是因为查字典。由于使用字符串作为键的dict在python中非常常见,因此当指针比较返回false时,您可以通过执行闪电般快速的指针比较(使用较慢的strcmp)来加速哈希函数/键的相等性检查。

使用
=
进行值比较,使用
is
进行参考比较。如果对象具有相同的
id
,则其计算结果为
True
,否则与
str()
一样,
id
会被更改,因此您会得到
False

使用
is
运算符比较两个操作数的内存位置。由于字符串是不可变的,
's'
's'
在内存中占据相同的位置

由于python2.7中处理unicode的方式,
u的
以相同的方式/位置存储。因此,它们占用相同的内存位置。因此,
's'是u's
的计算结果为
True

正如@mgilson指出的,
's'
u's'
属于不同的类型,因此不占用相同的内存位置,导致
's'is u's'
评估为
False

但是,当您调用
str(u's')
时,将创建并返回一个新字符串。这个新字符串由于是新创建的,所以位于内存中的新位置,这就是为什么
is
比较失败的原因

您真正想要的是检查它们是否是等效字符串,因此请使用
=

In [1]: 's' == u's'
Out[1]: True

In [2]: 's' == 's'
Out[2]: True

In [3]: 's' == str(u's')
Out[3]: True

你想知道的关于
“s”的一切都是u“s”
不应该计算为
真的
。他们是不同类型的。。。(至少在python2.x--Python3.3上,当他们重新引入
u
literal时,我想你可以得到
True
。)
>>> if 's' is str(u's'): print "Hurrah!"
... 
>>> type('s')
<type 'str'>

>>> type(str(u's'))
<type 'str'>
In [1]: 's' == u's'
Out[1]: True

In [2]: 's' == 's'
Out[2]: True

In [3]: 's' == str(u's')
Out[3]: True