使用'is'比较两个字符串 -- 结果不如预期
我正在尝试用is来比较两个字符串。一个字符串是通过一个函数返回的,另一个字符串则是在比较时直接写出来的。is用来检查两个对象是否是同一个,但根据这个页面的说法,它也可以用在两个相同的字符串上,因为Python会进行内存优化。不过,下面的代码却没有成功:
def uSplit(ustring):
#return user minus host
return ustring.split('!',1)[0]
user = uSplit('theuser!host')
print type(user)
print user
if user is 'theuser':
print 'ok'
else:
print 'failed'
user = 'theuser'
if user is 'theuser':
print 'ok'
输出结果是:
type 'str' theuser failed ok
我猜测原因是通过函数返回的字符串和直接写的字符串在“类型”上是不同的。那么有没有办法让函数返回一个字符串字面量呢?我知道可以用==来比较,但我只是好奇。
3 个回答
你遇到的问题是,Python并不是总会把所有的字符串都存储在一个地方。想了解更多细节,可以看看这里:
http://mail.python.org/pipermail/tutor/2009-July/070157.html
你引用的那一页说:“如果两个字符串字面量相等,它们就被放在了同一个内存位置”(强调是我加的)。在Python中,字面量字符串会被“内部管理”,也就是说相同的字符串会共享同一块内存。但是,如果字符串是从某个任意函数返回的,那它们就是不同的对象。is
运算符可以理解为比较指针,所以两个不同的对象不会被认为是相同的(即使它们的内容是一样的,也就是它们是相等的)。
你引用的网站上说:
如果两个字符串字面量相等,它们就被放在了同一个内存位置。
但是
uSplit('theuser!host')
并不是一个字符串字面量——它是对字面量 'theuser!host'
进行操作的结果。
总之,通常你不应该用 is
来检查字符串是否相等,因为这种内存优化其实只是实现细节,你不应该依赖它。
另外,你应该用 is
来检查像 is None
这样的情况。用它来检查你自己设计的类的两个对象是否是同一个实例。对于字符串或数字,你不容易使用它,因为这些内置类的创建规则比较复杂。有些字符串是“内存共享”的,类似地,有些数字也是“内存共享”的。