Python 比较unicode对象和字符串对象时的奇怪行为
在python中比较两个字符串时,它工作正常,当比较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'> >
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